题目:
题解:
把第一次在这个区间内出现的所有数字标1,求区间和......
在第一次出现这个数的地方标1,当你的左边(d[i].l)路过的时候,你的1应该消失并去到下一个这样的数字上-----基本思路
(或者:当你的右边(d[i].r)路过的时候,你的1应该出现并让上一个这样的数消失
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int c[50005],a[50005],ans[50005],pd[1000005];
int n,m;
struct hh{int l,r,num;}d[50005];
int cmp(hh a,hh b){return a.r<b.r;}
void add(int loc,int value)
{
for (int i=loc;i<=n;i+=i&(-i))
c[i]+=value;
}
int qurry(int loc)
{
int ans=0;
for (int i=loc;i>0;i-=i&(-i))
ans+=c[i];
return ans;
}
int main()
{
int i,j;
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for (i=1;i<=m;i++)
{
scanf("%d%d",&d[i].l,&d[i].r);
d[i].num=i;
}
sort(d+1,d+m+1,cmp);
int l=0,r=1,ll,k=1;
for (i=1;i<=n;i++)
{
if (!pd[a[i]])
{
pd[a[i]]=i;
add(i,1);
}
else
{
add(pd[a[i]],-1);
add(i,1); pd[a[i]]=i;
}
while (d[k].r==i)
{
ans[d[k].num]=qurry(d[k].r)-qurry(d[k].l-1);
k++;
}
}
for (i=1;i<=m;i++)
printf("%d\n",ans[i]);
}