转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
int s[N],a[N]; int n,q,ans[M]; int nxt[N]; map<int,int >mp; struct Question{ int l,r,id; bool operator<(const Question q)const{ return l<q.l; } }Q[M]; void add(int x,int val){ for(int i=x;i<=n;i+=lowbit(i)) s[i]+=val; } int query(int x){ int ret=0; for(int i=x;i>0;i-=lowbit(i)) ret+=s[i]; return ret; } int main(){ while(scanf("%d",&n)!=EOF){ mp.clear(); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); if(mp.find(a[i])==mp.end()){ mp[a[i]]=i; add(i,1); } } mp.clear(); for(int i=n;i;i--){ if(mp.find(a[i])==mp.end()) nxt[i]=n+1; else nxt[i]=mp[a[i]]; mp[a[i]]=i; } scanf("%d",&q); for(int i=0;i<q;i++){ scanf("%d%d",&Q[i].l,&Q[i].r); Q[i].id=i; } sort(Q,Q+q); int t=1; for(int i=0;i<q;i++){ while(t<=n&&t<Q[i].l) add(nxt[t++],1); ans[Q[i].id]=query(Q[i].r)-query(Q[i].l-1); } for(int i=0;i<q;i++) printf("%d\n",ans[i]); } return 0; }
map<int,int>mp; int a[N],tot,n,q; int T[M],lson[M],rson[M],val[M]; int bulid(int l,int r){ int root=tot++; val[root]=0; int m=(l+r)>>1; if(l!=r){ lson[root]=bulid(l,m); rson[root]=bulid(m+1,r); } return root; } int update(int root,int pos,int v){ int newroot=tot++,tmp=newroot; int l=1,r=n; val[newroot]=val[root]+v; while(l<r){ int m=(l+r)>>1; //更新的时候需要充分利用历史信息 //更新原来的左子树,右子树不变 if(pos<=m){ lson[newroot]=tot++;rson[newroot]=rson[root]; newroot=lson[newroot];root=lson[root]; r=m; } //更新右子树 else{ rson[newroot]=tot++;lson[newroot]=lson[root]; newroot=rson[newroot];root=rson[root]; l=m+1; } val[newroot]=val[root]+v; } return tmp; } int query(int root,int pos){ int ret=0; int l=1,r=n; while(pos<r){ int m=(l+r)>>1; if(pos<=m){ r=m; root=lson[root]; } else{ ret+=val[lson[root]]; root=rson[root]; l=m+1; } } return ret+val[root]; } int main(){ while(scanf("%d",&n)!=EOF){ tot=0; //结点数 for(int i=1;i<=n;i++) scanf("%d",&a[i]); T[n+1]=bulid(1,n); for(int i=n;i;i--){ int nxt; map<int,int>::iterator it=mp.find(a[i]); if(it==mp.end()) nxt=n+1; else nxt=it->second; //如果这是第一次出现,也就是最后一个位置上,则直接更新 if(nxt>n) T[i]=update(T[i+1],i,1); //在原来的位置上擦掉,在当前位置更新 else{ int t=update(T[i+1],nxt,-1); T[i]=update(t,i,1); } mp[a[i]]=i; } scanf("%d",&q); while(q--){ int l,r; scanf("%d%d",&l,&r); printf("%d\n",query(T[l],r)); } } return 0; }