题意:给n个数,m次查询,求[l,r]之间不重复数的个数。
思路:主席树。用一个map记录每个值在当前操作下最新的位置,从前往后插入主席树。对于查询[l,r],窝们在root[ l ]下查询在r之前的不重复数的个数。详见代码:
/********************************************************* file name: spoj3267.cpp author : kereo create time: 2015年04月04日 星期六 14时29分56秒 *********************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<map> #include<vector> #include<stack> #include<cmath> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int sigma_size=26; const int N=100+50; const int MAXN=30000+50; const int inf=0x3fffffff; const double eps=1e-8; const int mod=1000000000+7; #define L(x) (x->ch[0]) #define R(x) (x->ch[1]) #define PII pair<int, int> #define mk(x,y) make_pair((x),(y)) int n,m,cnt,top; int a[MAXN],st[MAXN*30]; struct node{ int num; node *ch[2]; }nod[MAXN*30],*root[MAXN],nil,*null; map<int,int>mp; struct CMT{ void init(){ cnt=top=0; nil.num=0; null=&nil; L(null)=R(null)=null; for(int i=0;i<=n+1;i++) root[i]=null; } void newnode(node * &x,node *fa,int val){ if(top) x=&nod[st[--top]]; else x=&nod[cnt++]; if(fa == null){ x->num=val; L(x)=R(x)=null; } else{ x->num=fa->num+val; L(x)=L(fa); R(x)=R(fa); } } void insert(node *&rt,node *fa,int l,int r,int pos,int val){ newnode(rt,fa,val); if(l == r) return ; int mid=(l+r)>>1; if(pos<=mid) insert(L(rt),L(fa),l,mid,pos,val); else insert(R(rt),R(fa),mid+1,r,pos,val); } int query(node *rt,int pos){ int l=1,r=n,ans=0; while(pos<r){ int mid=(l+r)>>1; if(pos<=mid){ rt=L(rt); r=mid; } else{ ans+=L(rt)->num; rt=R(rt); l=mid+1; } } return ans+rt->num; } }cmt; int main(){ //freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ for(int i=1;i<=n;i++) scanf("%d",&a[i]); cmt.init(); mp.clear(); for(int i=n;i>=1;i--){ if(mp.find(a[i]) == mp.end()) cmt.insert(root[i],root[i+1],1,n,i,1); else{ cmt.insert(root[0],root[i+1],1,n,mp[a[i]],-1); cmt.insert(root[i],root[0],1,n,i,1); } mp[a[i]]=i; } scanf("%d",&m); while(m--){ int l,r; scanf("%d%d",&l,&r); printf("%d\n",cmt.query(root[l],r)); } } return 0; }
时间: 2024-10-12 13:09:02