UVA 11922 Permutation Transformer(splay树)

来源:互联网 发布:阿里云免费套餐9.9 编辑:程序博客网 时间:2024/05/16 00:39

建树时节点加1,当需要旋转[a,b]的时候,其实分裂的是[a+1,b+1]的元素,所以增大一个节点,那么最后减一就可以了,如果序列的树很乱,那么用数组下标来建树。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct Node{    Node* ch[2];    int v,s;    int flip;    int cmp(int x) const {        int d=x-ch[0]->s;        if(d==1) return -1;        return (d<=0?0:1);    }    void maintain(){        s=1+ch[0]->s+ch[1]->s;    }    void pushdown(){        if(flip){            flip=0;            swap(ch[0],ch[1]);            ch[0]->flip=!ch[0]->flip;            ch[1]->flip=!ch[1]->flip;        }    }};Node* null=new Node();void rotate(Node* &o,int d){    Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;    o->maintain();k->maintain();o=k;}void splay(Node* &o,int k){    o->pushdown();    int d=o->cmp(k);    if(d==1) k-=o->ch[0]->s+1;    if(d!=-1)    {        Node* p=o->ch[d];        p->pushdown();        int d2=p->cmp(k);        int k2=(d2==0?k:k-p->ch[0]->s-1);        if(d2!=-1)        {            splay(p->ch[d2],k2);            if(d==d2) rotate(o,d^1);else rotate(o->ch[d],d);        }        rotate(o,d^1);    }}void split(Node* o,int k,Node* &left,Node* &right){    splay(o,k);    left=o;    right=o->ch[1];    o->ch[1]=null;    left->maintain();}Node* merge(Node* left,Node* right){    splay(left,left->s);    left->ch[1]=right;    left->maintain();    return left;}void build(Node* &o,int l,int r){    if(l>r) {o=null;return ;}    int mid=(l+r)/2;    o=new Node();    o->v=mid;    build(o->ch[0],l,mid-1);    build(o->ch[1],mid+1,r);    o->maintain();}void print(Node* o){    if(o!=null)    {        o->pushdown();        print(o->ch[0]);        if(o->v>1) printf("%d\n",o->v-1);        print(o->ch[1]);    }}void debug(Node* o,int f){    if(o!=null)    {        o->pushdown();        debug(o->ch[0],o->v);        printf("%d %d %d\n",o->v,f,o->s);        debug(o->ch[1],o->v);    }}void remove(Node* o){    if(o->ch[0]!=NULL) remove(o->ch[0]);    if(o->ch[1]!=NULL) remove(o->ch[1]);    delete o;    o=NULL;}Node* root;int main(){    int n,m;    scanf("%d%d",&n,&m);    build(root,1,n+1);//建树时节点加一//    debug(root,-1);cout<<endl;    while(m--)    {        int a,b;        scanf("%d%d",&a,&b);        Node *left,*mid,*right,*o;        split(root,a,left,o);        split(o,b-a+1,mid,right);        mid->flip^=1;        root=merge(merge(left,right),mid);//        debug(root,-1);cout<<endl;    }    print(root);    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 厚底皮拖鞋穿松了怎么办 白色帆布鞋洗后发黄怎么办 运动鞋子买大了怎么办 格力空调出现fo怎么办 绝味鸭脖代金券的附券撕了怎么办 耐克鞋子开胶了怎么办 苹果6s自动重启怎么办 钱不够想买手机怎么办 安卓机屏幕密码忘了怎么办 屏幕解锁密码忘了怎么办 华为手机屏幕解锁密码忘了怎么办 oppo锁屏密码忘了怎么办 云助理密码忘了怎么办 购买方发票丢了怎么办 普票发票联丢失怎么办 唯品金融没还款怎么办 金点原子锁打不开了怎么办 87彩店注册不了怎么办 微店如果不退款怎么办 微信上微商被骗怎么办 微商代理不做了怎么办 微店拒收不退款怎么办 在微商买东西被骗怎么办 云集买家买东西不退款怎么办 微信红包密码忘记了怎么办 微信购物不退货怎么办 微信隐私设置无法添加怎么办 微信支付被限额怎么办 微信发现没有购物怎么办 微信转账钱被骗怎么办 玩连环夺宝输了好多钱怎么办 厘米秀换不了装怎么办 社保只缴纳两年怎么办 502盖子粘到手上怎么办 口红粘在盖子上怎么办 玫瑰手杖永久错过了怎么办 手指沾到502胶水怎么办 我退款了货到了怎么办 世纪天成账号被盗什么也没绑怎么办 韩国电话卡不想用怎么办2018 汽车没有年检交警抓到怎么办