题目链接:[2459: Submissions of online judge](https://www.oj.swust.edu.cn/problem/show/2459)
题意:寻找区间内不同元素个数。
思路:想要找每个区间内元素不同元素个数,可以写莫队,但可能会被卡。下一种思路,对于[L,R],利用树状数组,寻找距离R最近的点即可。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int a[maxn],c[maxn];
int ans[maxn];
int n;
vector<pair<int,int>>v[maxn];
inline int read()
{
char ls=getchar();for (;ls<'0'||ls>'9';ls=getchar());
int x=0;for (;ls>='0'&&ls<='9';ls=getchar()) x=x*10+ls-'0';
return x;
}
inline int lowbit(int x)
{
return x&-x;
}
int add(int pos,int val)
{
for(int i=pos; i<=n; i+=lowbit(i))
{
c[i]+=val;
}
}
int Sum(int pos)
{
int ret=0;
for(int i=pos; i>0; i-=lowbit(i))
{
ret+=c[i];
}
return ret;
}
int main()
{
int T;
T=read();
while(T--)
{
memset(c,0,sizeof(c));
n=read();
for(int i=1; i<=n; i++)
{
v[i].clear();
}
for(int i=1; i<=n; i++)
{
a[i]=read();
}
int l,r,q;
q=read();
for(int i=1; i<=q; i++)
{
l=read();
r=read();
v[r].push_back(make_pair(l,i));
}
unordered_map<int,int>lastpos;
for(int i=1; i<=n; i++)
{
if(lastpos[a[i]]) add(lastpos[a[i]],-1);
lastpos[a[i]]=i;
add(lastpos[a[i]],1);
for(int j=0; j<v[i].size(); j++)
{
int L=v[i][j].first;
int R=i;
int id=v[i][j].second;
int sum=Sum(R)-Sum(L-1);
ans[id]=sum;
}
}
for(int i=1; i<=q; i++)
{
printf("%d\n",ans[i]);
}
}
return 0;
}