hdu 3487 Play with Chain

来源:互联网 发布:我的世界无限耐久js 编辑:程序博客网 时间:2024/05/16 11:05

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487

题目思路:splay,区间旋转和区间转移,区间转移的时候要注意向上更新,旋转的时候要注意rev要异或。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<string>#include<queue>#include<algorithm>#include<vector>#include<stack>#include<list>#include<iostream>#include<map>#define keytree ch[ch[root][1]][0]using namespace std;#define inf 0x3f3f3f3f#define Max 110#define M 300010int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}int p[M],ch[M][2],s[M],rev[M],v[M],ans[M];int top1,root,n,m,cnt=0;void up(int x){    s[x]=s[ch[x][0]]+s[ch[x][1]]+1;}void down(int x){    if(!rev[x]) return;    int l=ch[x][0],r=ch[x][1];    if(l)    {        swap(ch[l][0],ch[l][1]);        rev[l]^=1;    }    if(r)    {        swap(ch[r][0],ch[r][1]);        rev[r]^=1;    }    rev[x]=0;}void visit(int x){    if(!x) return;    down(x);   // printf("x %d p %d ch0 %d ch1 %d v %d rev %d \n",x,p[x],ch[x][0],ch[x][1],v[x],rev[x]);    visit(ch[x][0]);    ans[cnt++]=v[x];    visit(ch[x][1]);}void newnode(int &x,int val,int pre){    x=++top1;    s[x]=1;    ch[x][0]=ch[x][1]=rev[x]=0;    p[x]=pre;    v[x]=val;}void build(int &x,int l,int r,int pre){    if(l>r) return;    int mid=(l+r)>>1;    newnode(x,mid,pre);    build(ch[x][0],l,mid-1,x);    build(ch[x][1],mid+1,r,x);    up(x);}void init(){    top1=p[0]=ch[0][0]=ch[0][1]=v[0]=rev[0]=0;    newnode(root,-inf,0);    newnode(ch[root][1],inf,root);    s[root]=2;    build(keytree,1,n,ch[root][1]);    up(ch[root][1]);    up(root);}void rot(int x,int f){    int y=p[x];    p[ch[x][f]]=y;    ch[y][!f]=ch[x][f];    p[x]=p[y];    if(p[y]) ch[p[y]][ch[p[y]][1]==y]=x;    p[y]=x;    ch[x][f]=y;    up(y);}void splay(int x,int goal){    while(p[x]!=goal)    {        if(p[p[x]]==goal) rot(x,ch[p[x]][0]==x);        else        {            int y=p[x],f=ch[p[y]][0]==y;            if(ch[y][f]==x)            {                rot(x,!f);            }            else rot(y,f);            rot(x,f);        }    }    if(!goal) root=x;    up(x);}void rotto(int k,int goal){    int x=root;    down(x);    while(s[ch[x][0]]!=k)    {        if(s[ch[x][0]]>k)            x=ch[x][0];        else        {            k-=s[ch[x][0]]+1;            x=ch[x][1];        }        down(x);    }    splay(x,goal);}void Rev(int l,int r){    rotto(l-1,0);    rotto(r+1,root);   // visit(root);    rev[keytree]^=1;    swap(ch[keytree][0],ch[keytree][1]);  //  visit(root);}void cut(int l,int r,int c){    rotto(l-1,0);    rotto(r+1,root);    int x=keytree;    keytree=0;    up(ch[root][1]);    up(root);    rotto(c,0);    rotto(c+1,root);    keytree=x;    p[x]=ch[root][1];    up(ch[root][1]);    up(root);}int main(){    char op[10];    int a,b,c;    while(scanf("%d%d",&n,&m)!=EOF)    {        if(n<0&&m<0)            break;        cnt=0;        init();       // visit(root);        while(m--)        {            scanf("%s",op);            if(op[0]=='C')            {                scanf("%d%d%d",&a,&b,&c);                cut(a,b,c);            }            else            {                scanf("%d%d",&a,&b);                Rev(a,b);            }        }        visit(root);        printf("%d",ans[1]);        for(int i=2;i<cnt-1;i++)        {            printf(" %d",ans[i]);        }        puts("");    }}


 

原创粉丝点击