CODEVS 1343(伸展树)

来源:互联网 发布:世界顶级音乐学院知乎 编辑:程序博客网 时间:2024/06/05 17:03

题目链接:http://codevs.cn/problem/1343/

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 100020int c[N][2],fa[N],mx[N],sz[N];int v[N];int n,m,rt;void pushup(int x){    int l=c[x][0],r=c[x][1];    sz[x]=sz[l]+sz[r]+1;    mx[x]=max(v[x],max(mx[l],mx[r]));}void build(int l,int r,int f){    if(l>r) return;    int now=l,last=f;    if(l==r)    {        c[now][0]=c[now][1]=0;fa[now]=last;        if(l<f) c[last][0]=now;else c[last][1]=now;        pushup(now);return;    }    int mid=l+r>>1;now=mid;    build(l,mid-1,mid);build(mid+1,r,mid);    if(l<f) c[last][0]=now;else c[last][1]=now;    fa[now]=last;pushup(now);}void rotate(int x,int &k){    int y=fa[x],z=fa[y],l,r;    if(c[y][0]==x) l=0;else l=1;r=l^1;    if(y==k) k=x;    else if(c[z][0]==y) c[z][0]=x;else c[z][1]=y;    fa[x]=z;fa[c[x][r]]=y;fa[y]=x;    c[y][l]=c[x][r];c[x][r]=y;    pushup(y);pushup(x);}void splay(int x,int &k){    while(x!=k)    {        int y=fa[x],z=fa[y];        if(y!=k)        {            if(c[z][0]==y^c[y][0]==x) rotate(x,k);            else rotate(y,k);        }        else rotate(x,k);    }}int Find(int k,int rank){    int l=c[k][0],r=c[k][1];    if(rank<=sz[l]) return Find(l,rank);    else if(rank==sz[l]+1) return k;    else return Find(r,rank-sz[l]-1);}int del(int rank){    int x=Find(rt,rank-1),y=Find(rt,rank+1),z;    splay(x,rt);splay(y,c[x][1]);    z=c[y][0];fa[z]=0;c[y][0]=0;    pushup(y);pushup(x);    return z;}void move_left(int rank,int l,int r){    int z=del(rank);    int x=Find(rt,l-1),y=Find(rt,r+1);    splay(x,rt);splay(y,c[x][1]);    printf("%d\n",mx[c[y][0]]);    fa[y]=z;fa[z]=x;c[x][1]=z;c[z][0]=0;c[z][1]=y;    pushup(z);pushup(x);    splay(z,rt);}void move_right(int rank,int l,int r){    int z=del(rank);    int x=Find(rt,r+1),y=Find(rt,l-1);    splay(x,rt);splay(y,c[x][0]);    printf("%d\n",mx[c[y][1]]);    fa[y]=z;fa[z]=x;c[x][0]=z;c[z][0]=y;c[z][1]=0;    pushup(z);pushup(x);    splay(z,rt);}int main(){    scanf("%d%d",&n,&m);    for(int i=2;i<=n+1;++i) scanf("%d",&v[i]);    build(1,n+2,0);rt=n+3>>1;    int x,d;    char ch[10];    while(m--)    {        scanf("%d%s%d",&x,ch,&d);        if(ch[0]=='L') move_left(x+1,x-d+1,x);        else move_right(x+1,x+1,x+d);    }    return 0;}