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

 

posted @ 2018-08-04 01:11  wang9897  阅读(145)  评论(0编辑  收藏  举报