BZOJ3489: A simple rmq problem
队友丢过来的毒瘤数据结构 ...KDtree模板题?告辞 不会KDtree ....那我只能考虑别的做法了 很显然 每个a[i] 都有上一个出现的位置last和下一个出现的位置next 对于查询的区间而言 当且仅当 [l,r]属于(last,next)的子集时并且了l<=i<=r这点的值才会产生贡献 因此 我们考虑主席树维护以pos为位置的历史版本 对于主席树中的[next,n]区间更新对应的动态开点的线段树中插入[i,a[i]] 查询就是普通的树套树的查询即可 空间(nlog^2n) 时间(nlog^2n)
做法:主席树+动态开点线段树
/************************************************************** Problem: 3489 User: c20161007 Language: C++ Result: Accepted Time:23948 ms Memory:476340 kb ****************************************************************/ #include <bits/stdc++.h> const int MAXN=1e5+10; #define ll long long using namespace std; ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return f*x; } int vis[MAXN]; typedef struct node{ int l,r,vul,id; friend bool operator<(node aa,node bb){ return aa.l<bb.l; } }node; node que[MAXN];int rt[MAXN]; typedef struct Node{ int l,r,id; }Node; Node d[32*MAXN];int a[MAXN]; int cnt,cnt1,cnt2,n,m; typedef struct nOde{ int l,r,max; }nOde; nOde D[371*MAXN]; void update1(int &x,int y,int l,int r,int t,int vul){ x=++cnt2;D[x]=D[y];D[x].max=max(vul,D[x].max); //cout<<l<<" "<<r<<" "<<t<<" "<<vul<<endl; if(l==r)return ; int mid=(l+r)>>1; if(t<=mid)update1(D[x].l,D[y].l,l,mid,t,vul); else update1(D[x].r,D[y].r,mid+1,r,t,vul); } int t1; void update(int &x,int y,int l,int r,int t,int vul){ x=++cnt;d[x]=d[y];update1(d[x].id,d[y].id,1,n,t1,vul); // cout<<l<<":::"<<r<<" "<<d[x].id<<endl; if(l==r)return ; int mid=(l+r)>>1; if(t<=mid)update(d[x].l,d[y].l,l,mid,t,vul); else update(d[x].r,d[y].r,mid+1,r,t,vul); } int ans=0; int Ql,Qr; void querty1(int x,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){ans=max(ans,D[x].max);return ;} int mid=(l+r)>>1; if(ql<=mid)querty1(D[x].l,l,mid,ql,qr); if(qr>mid)querty1(D[x].r,mid+1,r,ql,qr); } void querty(int x,int l,int r,int ql,int qr){ // cout<<l<<" "<<r<<" "<<d[x].id<<endl; if(ql<=l&&r<=qr){querty1(d[x].id,1,n,Ql,Qr);return ;} int mid=(l+r)>>1; if(ql<=mid)querty(d[x].l,l,mid,ql,qr); if(qr>mid)querty(d[x].r,mid+1,r,ql,qr); } int main(){ n=read();m=read(); for(int i=1;i<=n;i++)que[i].vul=read(),a[i]=que[i].vul,que[i].id=i; for(int i=1;i<=n;i++)que[i].l=vis[a[i]]+1,vis[a[i]]=i; for(int i=1;i<=n;i++)vis[i]=n+1; for(int i=n;i>=1;i--)que[i].r=vis[a[i]]-1,vis[a[i]]=i; sort(que+1,que+n+1); // for(int i=1;i<=n;i++)cout<<que[i].l<<" "<<que[i].r<<" "<<que[i].vul<<endl; int L=1; for(int i=1;i<=n;i++){ // cout<<que[i].l<<" "<<L<<endl; while(L<que[i].l)rt[L]=rt[L-1],L++; t1=que[i].id; if(que[i].l!=que[i-1].l)update(rt[que[i].l],rt[que[i].l-1],1,n,que[i].r,que[i].vul),L++; else update(rt[que[i].l],rt[que[i].l],1,n,que[i].r,que[i].vul); // cout<<que[i].l<<" "<<rt[que[i].l]<<" "<<L<<endl; } for(;L<=n;L++)rt[L]=rt[L-1]; // for(int i=1;i<=n;i++)cout<<rt[i]<<" "; // cout<<endl; //for(int i=1;i<=n;i++)vis[i]=0; //for(int i=1;i<=n;i++)L[i]=R[vis[a[i]]]+1,vis[a[i]]=i; int l,r,lx,rx,res=0; for(int i=1;i<=m;i++){ l=read();r=read();lx=l;rx=r; //cout<<l<<" "<<r<<endl; lx=min((l+res)%n+1,(r+res)%n+1); rx=max((l+res)%n+1,(r+res)%n+1); // cout<<lx<<":::"<<rx<<" "<<rt[lx]<<endl; Ql=lx;Qr=rx; ans=0;querty(rt[lx],1,n,rx,n);res=ans; //ans=0;querty(1,1,n,r,n);res printf("%d\n",res); } return 0; }