HDU 5919 (還算基礎的主席樹)
阿新 • • 發佈:2019-02-06
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <map> using namespace std; const int MAX=2e5+500; int a[MAX],root[MAX]; map<int,int >mp; struct { int l,r,sum; } T[MAX*40]; int cnt=0; void update(int l,int r,int &x,int y,int pos,int v) { T[++cnt]=T[y]; x=cnt; T[cnt].sum+=v; if(l==r) return ; int mid=(r+l)>>1; if(pos<=mid) { update(l,mid,T[cnt].l,T[y].l,pos,v); } else update(mid+1,r,T[cnt].r,T[y].r,pos,v); } int query(int rt,int l,int r,int L,int R) { if(L<=l&&R>=r) return T[rt].sum; int mid=(l+r)>>1; int ans=0; if(L<=mid) ans+=query(T[rt].l,l,mid,L,R); if(R>mid) ans+=query(T[rt].r,mid+1,r,L,R); return ans; } int he(int rt,int l,int r,int k) { if(l==r) return l; int m=(l+r)>>1; int tmp=T[T[rt].l].sum; if(k<=tmp) return he(T[rt].l,l,m,k); else return he(T[rt].r,m+1,r,k-tmp); } void init() { mp.clear(); cnt=0;//忘記初始化cnt,bug了很長時間。 memset(root,0,sizeof(root)); } int main() { int n,t,q; int cas=1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&q); for(int i=1; i<=n; i++) scanf("%d",&a[i]); init(); T[n+1].l=T[n+1].r=T[n+1].sum=0; for(int i=n; i>=1; i--) { if(mp[a[i]]==0) update(1,n,root[i],root[i+1],i,1); else { int tmp; update(1,n,tmp,root[i+1],mp[a[i]],-1); update(1,n,root[i],tmp,i,1); } mp[a[i]]=i; } printf("Case #%d:",cas++); int ans=0; while(q--) { int x,y,l,r; scanf("%d%d",&x,&y); x=(x+ans)%n+1; y=(y+ans)%n+1; l=min(x,y); r=max(x,y); int k=(query(root[l],1,n,l,r)+1)>>1; // cout<<k<<endl; ans=he(root[l],1,n,k); printf(" %d",ans); } printf("\n"); } return 0; }