【codevs1343】[HNOI]蚱蜢

= =鬼知道這是那年的HNOI題,連bzoj上都沒有,其實就是維護一個平衡樹就好了,然後區間查詢,支持刪點加點。
涉及區間操作注意在兩旁添加結點後原數組的標號改動問題,這道題相對來說調的比較快

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>

using namespace std;
const int N=200010,inf=0x3f3f3f3f;
int n,m;
int sz,root;
int a[N],ch[N][2],size[N],key[N],mx[N],fa[N];
inline void clear(int x){ch[x][0]=ch[x][1]=size[x]=fa[x]=key[x]=0;}
inline void updata(int x)
{
    if (x)
    {
        size[x]=1;
        mx[x]=key[x];
        if (ch[x][0])
        {
            size[x]+=size[ch[x][0]];
            mx[x]=max(mx[x],mx[ch[x][0]]);
        }
        if (ch[x][1])
        {
            size[x]+=size[ch[x][1]];
            mx[x]=max(mx[x],mx[ch[x][1]]);
        }
    }
}
inline int get(int x){return ch[fa[x]][1]==x;}
inline void rotate(int x)
{
    int old=fa[x],oldf=fa[old],which=get(x);
    ch[old][which]=ch[x][which^1],fa[ch[old][which]]=old;
    ch[x][which^1]=old;fa[old]=x;fa[x]=oldf;
    if (oldf)ch[oldf][ch[oldf][1]==old]=x;
    updata(old);updata(x);
}
inline void splay(int x,int tar)
{
    for (int old;(old=fa[x])!=tar;rotate(x))
    if (fa[old]!=tar)rotate(get(x)==get(old)?old:x);
    if (!tar)root=x;
}
inline int build(int l,int r,int old)
{
    if (l>r)return 0;
    int now=++sz;
    int mid=(l+r)>>1;
    key[now]=a[mid];mx[now]=a[mid],size[now]=1;fa[now]=old;
    ch[now][0]=build(l,mid-1,now);
    ch[now][1]=build(mid+1,r,now);
    updata(now);
    return now;
}
inline int find(int x)
{
    int now=root;
    while(1)
    {
        if (ch[now][0]&&x<=size[ch[now][0]])
        now=ch[now][0];
        else 
        {
            int temp=1;
            if (ch[now][0])
            temp+=size[ch[now][0]];
            if (x<=temp)return now;
            x-=temp;
            now=ch[now][1];
        }
    }
}
inline int findval(int x)
{
    int now=root;
    while(1)
    {
        if (ch[now][0]&&x<=size[ch[now][0]])now=ch[now][0];
        else 
        {
            int temp=1;
            if (ch[now][0])
            temp+=size[ch[now][0]];
            if (x<=temp)return key[now];
            x-=temp;now=ch[now][1];
        }
    }
}
inline void query(int l,int r)
//L-1,R+1
{
    int aa=find(l);
    int bb=find(r+2);
    splay(aa,0);
    splay(bb,aa);
    int ans=mx[ch[ch[root][1]][0]];
    printf("%d\n",ans);
    updata(ch[root][1]);
    updata(root);
}
inline void insert(int x,int val)
{
    int aa=find(x);
    int bb=find(x+1);
    splay(aa,0);
    splay(bb,aa);
    ch[ch[root][1]][0]=++sz;
    fa[sz]=ch[root][1];
    ch[sz][0]=ch[sz][1]=0;
    key[sz]=val;mx[sz]=val;
    size[sz]=1;updata(fa[sz]);
    updata(root);
}
inline void del(int x)
{
    int aa=find(x);
    int bb=find(x+2);
    splay(aa,0);
    splay(bb,aa);
    ch[ch[root][1]][0]=0;
    updata(ch[root][1]);
    updata(root);
}
int main()
{
    int st,cnt;
    scanf("%d%d",&n,&m);
    a[1]=-inf,a[n+2]=inf;
    for (int i=1;i<=n;++i)
    scanf("%d",&a[i+1]);
    root=build(1,n+2,0);
    for (int i=1;i<=m;++i)
    {   
        scanf("%d",&st);
        char c=getchar();
        while(c!='L'&&c!='D')c=getchar();
        scanf("%d",&cnt);
        if (c=='L')
        {   
            int L=st-cnt;
            int R=st-1;
            query(L,R);
            int val=findval(st+1);
            del(st);
            insert(L,val);
        }   
        else 
        {
            int L=st+1;
            int R=st+cnt;
            query(L,R);
            int val=findval(st+1);
            del(st);
            insert(R,val);
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章