输入输出样例
https://www.luogu.org/problemnew/show/P1972
输入样例#1: 复制 输出样例#1: 复制
6 2 1 2 3 4 3 5 2 3 4 1 2 3 5 2 6
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 5000010
#define maxm 200010
struct node
{
int l,r,no;
}c[maxm];
int n,m;
int tree[maxn],front[maxn],last[maxn];
int ans[maxm];
bool cmp(node x,node y)
{
return x.r<y.r;
}
int lowbit(int i)
{
return i&(-i);
}
void update(int i,int x)
{
while(i<=maxn)
{
tree[i]+=x;
i+=lowbit(i);
}
}
int query(int i)
{
int sum=0;
while(i>0)
{
sum+=tree[i];
i-=lowbit(i);
}
return sum;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int temp;
scanf("%d",&temp);
front[i]=last[temp]+1;//front数组为i位置上的数上一次出现的位置+1
last[temp]=i;//last数组为i位置上的数到目前为止最后一次出现的位置
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&c[i].l,&c[i].r);
c[i].no=i;//每次查询的序号
}
sort(c+1,c+1+m,cmp);//按右端点排序
int k=1;//k初值为1
for(int i=1;i<=m;i++)
{
while(k<=c[i].r)
{
k++;
update(front[k-1],1);
update(k,-1);
}
ans[c[i].no]=query(c[i].l);//查询左端点
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}