1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define M 1000008 5 using namespace std; 6 int sum[M],mx,n,next[M],p[M],a[M],m; 7 struct data 8 { 9 int l,r,o,ans; 10 }q[M]; 11 bool cmp(data a1,data a2) 12 { 13 if(a1.l==a2.l) 14 return a1.r<a2.r; 15 return a1.l<a2.l; 16 } 17 bool cmp1(data a1,data a2) 18 { 19 return a1.o<a2.o; 20 } 21 void add(int a1,int a2) 22 { 23 for(int i=a1;i<=n;i+=i&-i) 24 sum[i]+=a2; 25 return; 26 } 27 int xun(int a1) 28 { 29 int su=0; 30 for(int i=a1;i;i-=i&-i) 31 su+=sum[i]; 32 return su; 33 } 34 int main() 35 { 36 scanf("%d",&n); 37 for(int i=1;i<=n;i++) 38 { 39 scanf("%d",&a[i]); 40 mx=max(mx,a[i]); 41 } 42 for(int i=n;i;i--) 43 { 44 next[i]=p[a[i]]; 45 p[a[i]]=i; 46 } 47 scanf("%d",&m); 48 for(int i=1;i<=m;i++) 49 { 50 scanf("%d%d",&q[i].l,&q[i].r); 51 q[i].o=i; 52 } 53 for(int i=1;i<=mx;i++) 54 if(p[i]) 55 add(p[i],1); 56 sort(q+1,q+m+1,cmp); 57 int l=1; 58 for(int i=1;i<=m;i++) 59 { 60 for(;l<q[i].l;) 61 { 62 if(next[l]) 63 add(next[l],1); 64 l++; 65 } 66 q[i].ans=xun(q[i].r)-xun(q[i].l-1); 67 } 68 sort(q+1,q+m+1,cmp1); 69 for(int i=1;i<=m;i++) 70 printf("%d\n",q[i].ans); 71 return 0; 72 }
将读入离线处理,先排序,树状数组维护。