题解:
和上一题基本相同
插入的时候变一下数值
具体看http://www.cnblogs.com/xuanyiming/p/7921926.html
代码:
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; const int N=50005; typedef long long ll; struct Tree { ll num; int ls,rs; }T[N*20]; int now,rt[N],la[N*20],n,m,cnt=1,x,y,k,a[N]; int build(int l,int r) { now++; if (l==r)return now; int k=now,mid=(l+r)/2; if (l<=mid)T[k].ls=build(l,mid); if (mid<r)T[k].rs=build(mid+1,r); return k; } int insert(int x,int l,int r,int s,int kk) { now++; if (l==r) { T[now].num=T[x].num+kk; return now; } int k=now,mid=(l+r)/2; if (s<=mid) { T[k].ls=insert(T[x].ls,l,mid,s,kk); T[k].rs=T[x].rs; } else { T[k].ls=T[x].ls; T[k].rs=insert(T[x].rs,mid+1,r,s,kk); } T[k].num=T[T[k].ls].num+T[T[k].rs].num; return k; } ll find(int s,int x,int y,int l,int r) { if (l>y||r<x)return 0; if (x<=l&&y>=r)return T[s].num; ll ans=0; int mid=(l+r)/2; if (x<=mid)ans+=find(T[s].ls,x,y,l,mid); if (y>mid)ans+=find(T[s].rs,x,y,mid+1,r); return ans; } int main() { int cas; scanf("%d",&cas); while (cas--) { scanf("%d",&n); memset(T,0,sizeof T); memset(la,0,sizeof la); cnt=now=0; for (int i=1;i<=n;i++)scanf("%d",&a[i]); scanf("%d",&m); rt[0]=build(0,n); for (int i=1;i<=n;i++) { if (!la[a[i]])rt[i]=insert(rt[i-1],0,n,0,a[i]); else rt[i]=insert(rt[i-1],0,n,la[a[i]],a[i]); la[a[i]]=i; } while (m--) { scanf("%d%d",&x,&y); printf("%lld\n",find(rt[y],0,x-1,0,n)-find(rt[x-1],0,x-1,0,n)); } } return 0; }