一道莫队的裸题,数据是题目1972《HH的项链》的弱化版
题意:给定一组序列,含n个数,在给定的m个询问中回答区间l到r含多少个不同的数
题解:先将序列中的数离散化成1-n的数,然后采用离线莫队
#include<bits/stdc++.h> using namespace std; const int maxn=30000+10; const int M=200000+10; struct node{ int id,l,r,ans; }q[M]; int col[maxn],res,n,t,m; int be[maxn],a[maxn],b[maxn]; bool cmp1(node a,node b) { return be[a.l]==be[b.l]?a.r<b.r:a.l<b.l; } bool cmp2(node a,node b) { return a.id<b.id; } void del(int x) { if(--col[a[x]]==0) res--; } void add(int x) { if(++col[a[x]]==1) res++; } int found(int x) { int mid,l=1,r=t; while(l<=r) { mid=(l+r)>>1; if(x==b[mid]) return mid; if(x<b[mid]) r=mid-1; else l=mid+1; } } int main() { scanf("%d",&n); int k=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),be[i]=i/k+1,b[i]=a[i]; sort(b+1,b+1+n); t=unique(b+1,b+1+n)-b-1; for(int i=1;i<=n;i++) a[i]=found(a[i]); scanf("%d",&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,cmp1); int l=q[1].l,r=q[1].r; for(int i=l;i<=r;i++) add(i); for(int i=1;i<=m;i++) { while(l<q[i].l) del(l),l++; while(l>q[i].l) l--,add(l); while(r<q[i].r) r++,add(r); while(r>q[i].r) del(r),r--; q[i].ans=res; } sort(q+1,q+1+m,cmp2); for(int i=1;i<=m;i++) printf("%d ",q[i].ans); return 0; }