洛谷的分块练习题
看到讨论中说分块莫队被卡就写了树状数组...(但感觉做法和莫队的思想有点像?)
#include<bits/stdc++.h> using namespace std; const int N=5e5+7; const int M=1e6+7; int c[N],a[N],n,m; struct node{ int l,r,ans,id; }q[N]; bool cmp(node a,node b){//按r排序 return a.r==b.r?a.l<b.l:a.r<b.r; } bool cmpp(node a,node b){ return a.id<b.id; } void add(int x,int y){ while(x<=N){ c[x]+=y; x+=x&-x; } } int ask(int x){ int y=0; while(x){ y+=c[x]; x-=x&-x; } return y; } int used[M]; int main(){ cin>>n; for(int i=1;i<=n;i++) scanf("%d",&a[i]); cin>>m; for(int i=1;i<=m;i++){ scanf("%d%d",&q[i].l,&q[i].r); q[i].id=i; } sort(q+1,q+1+m,cmp); int now=1; for(int i=1;i<=m;i++){ for(int j=now;j<=q[i].r;j++){ if(!used[a[j]]){ add(j,1); used[a[j]]=j; } else { add(used[a[j]],-1);//必须减去之前的贡献再加上之后的贡献,否则在计算时会抵消。 add(j,1); used[a[j]]=j; } } now=q[i].r+1; q[i].ans=ask(q[i].r)-ask(q[i].l-1); } sort(q+1,q+1+m,cmpp); for(int i=1;i<=m;i++) printf("%d\n",q[i].ans); return 0; }