[ABC378C] Repeating 题解

题目大意

给你一个由 n n n 个正整数 a = ( a 1 , a 2 , … , a n ) a = (a_1, a_2, \dots, a_n) a=(a1,a2,,an) 组成的数列。让你求出对于每个 i i i前面 1 1 1 i − 1 i-1 i1 a i a_i ai这个数最晚出现的的位置,如果没有就输出 − 1 -1 1

解法

可以见得直接暴力枚举的复杂度是 O ( n 2 ) O(n^2) O(n2)的,很明显会超时。但是我们可以想到当你从 1 1 1开始遍历到多个重复的 a i a_i ai时,输出的答案只跟最后遍历到的 a i a_i ai的位置有关,因此我们可以拿一个桶 t t t来记录最后遍历到的 a i a_i ai的位置即可,当再次遍历到 a i a_i ai时只需输出 t a i t_{a_i} tai的值,并使 t a i = i t_{a_i}=i tai=i即可。

代码

#include<bits/stdc++.h>
using namespace std;
int n,a[500005];
//因为a的数据范围是1~1e9因此t要用map来存储。 
map<int,int> t;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		//如果前面没有a[i]出现过就输出-1,否则输出t[a[i]]。 
		if(t[a[i]]==0) cout<<"-1 ";
		else cout<<t[a[i]]<<" ";
		//更新t[a[i]]的值为i。 
		t[a[i]]=i;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值