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;
}

浙公网安备 33010602011771号