题目大意:给出n个数字m个 查询,然后查询的从第x个位置到最后一个位置,去重之后剩下几个数字.
一开始真的挺难想的.数据范围都是1e5,觉得应该是nlog的复杂度,联想到树状数组等.但是还是无果,看了题解之后顿时觉得自己好蠢
正应了先前的那句话
碰到题目难解的时候一定要反过来考虑.
反过来考虑的话就简单多了.从最后一个数开始,出现一个数,标记一个数.
如果当前的数出现过了,那么ans[i]=ans[i+1]否则就把这个数标记,然后ans[i]=ans[i+1]+1
即可解.
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int n,m;
int a[100005];
int vis[100005];
int ans[100005];
int main()
{
std::ios::sync_with_stdio(false);
//freopen("1.txt","r",stdin);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
ans[n]=1;
vis[a[n]]=1;
for(int i=n-1;i>=1;i--){
if(vis[a[i]]==1)
ans[i]=ans[i+1];
else {
ans[i]=ans[i+1]+1;
vis[a[i]]=1;
}
}
int x;
for(int i=0;i<m;i++){
cin>>x;
cout<<ans[x]<<endl;
}
return 0;
}
逆向思维解决去重查询问题
本文介绍了一种利用逆向思维解决特定查询问题的方法。通过对数据进行反向处理,实现了从最后一个元素开始标记已出现过的数字,从而高效地求解每个查询区间内不重复元素的数量。
321

被折叠的 条评论
为什么被折叠?



