zoukankan      html  css  js  c++  java
  • hdu3487Play with Chain(splay)

    链接

    简单的两种操作,一种删除某段区间,加在第I个点的后面,另一个是翻转区间。都是splay的简单操作。

    悲剧一:pushdown时候忘记让lz=0

    悲剧二:删除区间,加在某点之后的时候忘记修改其父亲节点。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 using namespace std;
     11 #define N 300010
     12 #define LL long long
     13 #define INF 0xfffffff
     14 #define key_value ch[ch[root][1]][0]
     15 const double eps = 1e-8;
     16 const double pi = acos(-1.0);
     17 const double inf = ~0u>>2;
     18 using namespace std;
     19 struct splay_tree
     20 {
     21     int pre[N],size[N];
     22     int ch[N][2];
     23     int root,tot,num,tot1;
     24     int key[N],lz[N];
     25     void dfs(int x)
     26     {
     27         if(x)
     28         {
     29             dfs(ch[x][0]);
     30             printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d lz = %d
    ",
     31                    x,ch[x][0],ch[x][1],pre[x],size[x],key[x],lz[x]);
     32             dfs(ch[x][1]);
     33         }
     34     }
     35     void debug()
     36     {
     37         printf("root:%d
    ",root);
     38         dfs(root);
     39     }
     40 //以上用于debug*/
     41     void newnode(int &x,int v,int fa)//新建一结点
     42     {
     43         x = ++tot;
     44         ch[x][0]=ch[x][1] = 0;
     45         pre[x] = fa;
     46         lz[x] = 0;
     47         size[x] = 1;
     48         key[x] = v;
     49     }
     50     void pushdown(int w)
     51     {
     52         if(lz[w])
     53         {
     54             int l = ch[w][0],r = ch[w][1];
     55             swap(ch[w][0],ch[w][1]);
     56 
     57             lz[l]^=lz[w];
     58             lz[r]^=lz[w];
     59             lz[w] = 0;
     60         }
     61     }
     62     void pushup(int w)//由儿子更新其父亲
     63     {
     64         size[w] = size[ch[w][0]]+size[ch[w][1]]+1;
     65         //cout<<s[w][0]<<" "<<s[w][1]<<endl;
     66     }
     67     void rotate(int r,int kind)//旋转操作,根据kind进行左旋和右旋
     68     {
     69         int y = pre[r];
     70         pushdown(y);
     71         pushdown(r);
     72         ch[y][!kind] = ch[r][kind];
     73         pre[ch[r][kind]] = y;
     74         if(pre[y])
     75         {
     76             ch[pre[y]][ch[pre[y]][1]==y] = r;
     77         }
     78         pre[r] = pre[y];
     79         ch[r][kind] = y;
     80         pre[y] = r;
     81         pushup(y);
     82         pushup(r);
     83     }
     84     void splay(int r,int goal)//将r结点旋至goal下
     85     {
     86         pushdown(r);
     87         while(pre[r]!=goal)
     88         {
     89             if(pre[pre[r]]==goal)
     90             {
     91                 rotate(r,ch[pre[r]][0]==r);
     92             }
     93             else
     94             {
     95                 int y = pre[r];
     96                 int kind = (ch[pre[y]][0]==y);
     97                 if(ch[y][kind]==r)
     98                 {
     99                     rotate(r,!kind);
    100                     rotate(r,kind);
    101                 }
    102                 else
    103                 {
    104                     rotate(y,kind);
    105                     rotate(r,kind);
    106                 }
    107             }
    108         }
    109         pushup(r);
    110         if(goal==0) root = r;
    111     }
    112     int get_k(int k)//得到第k个的结点
    113     {
    114         int r = root;
    115        pushdown(r);
    116         while(size[ch[r][0]]+1!=k)
    117         {
    118             if(size[ch[r][0]]>=k)
    119                 r = ch[r][0];
    120             else
    121             {
    122                 k-=(size[ch[r][0]]+1);//根据左右结点的数量来确定第k个节点在哪里
    123                 r = ch[r][1];
    124             }
    125             pushdown(r);
    126         }
    127         pushup(r);
    128         return r;
    129     }
    130     void cut(int l,int r,int k)
    131     {
    132         splay(get_k(l),0);
    133         splay(get_k(r+2),root);
    134         pushdown(ch[root][1]);
    135         int nod = key_value;
    136         ch[ch[root][1]][0] = 0;
    137         pre[nod] = 0;
    138         pushup(ch[root][1]);
    139         pushup(root);
    140         //debug();
    141         splay(get_k(k),0);
    142         splay(get_k(k+1),root);
    143         ch[ch[root][1]][0] = nod;
    144         pre[nod] = ch[root][1];
    145         pushup(ch[root][1]);
    146         pushup(root);
    147        // debug();
    148     }
    149     void filp(int l,int r)
    150     {
    151         //cout<<get_k(l)<<" "<<get_k(r+2)<<endl;
    152         splay(get_k(l),0);
    153         splay(get_k(r+2),root); //cout<<","<<endl;debug();
    154         lz[key_value]^=1;
    155         //swap(ch[key_value][0],ch[key_value][1]);
    156         pushup(ch[root][1]);
    157         pushup(root);
    158     }
    159     void work(int n)
    160     {
    161         int i;
    162         for(i = 1 ;i < n ;i++)
    163         {
    164             printf("%d ",key[get_k(i+1)]);
    165         }
    166         printf("%d
    ",key[get_k(n+1)]);
    167         //debug();
    168     }
    169     void build(int &x,int l,int r,int fa)
    170     {
    171         int m = (l+r)>>1;
    172         if(l>r) return ;
    173         newnode(x,m,fa);
    174         build(ch[x][0],l,m-1,x);
    175         build(ch[x][1],m+1,r,x);
    176         pushup(x);
    177     }
    178     void init(int o)
    179     {
    180         size[0] = ch[0][0] = ch[0][1] =  key[0] = lz[0] = 0;
    181         root = tot = 0;
    182         newnode(root,0,0);
    183         newnode(ch[root][1],0,root);
    184         build(ch[ch[root][1]][0],1,o,ch[root][1]);
    185         size[root] = 2;
    186         pushup(ch[root][1]);
    187         pushup(root);
    188     }
    189 }SP;
    190 int main()
    191 {
    192     int n,q;
    193     while(scanf("%d%d",&n,&q)!=EOF)
    194     {
    195         if(n==-1&&q==-1) break;
    196         SP.init(n);
    197         while(q--)
    198         {
    199             char sq[20];
    200             int k,x,y;
    201             scanf("%s",sq);
    202             if(sq[0]=='C')
    203             {
    204                 scanf("%d%d%d",&x,&y,&k);
    205                 SP.cut(x,y,k+1);
    206               // SP.debug();
    207 //                SP.work(n);
    208             }
    209             else
    210             {
    211                 //SP.debug();
    212                 scanf("%d%d",&x,&y);
    213                 SP.filp(x,y);
    214                 //SP.debug();
    215             }
    216             //SP.work(n);
    217         }
    218         SP.work(n);
    219     }
    220     return 0;
    221 }
    View Code
  • 相关阅读:
    C#之Raw Socket实现网络封包监视
    es6Promise及小程序Promise用法
    在微信小程序的JS脚本中使用Promise来优化函数处理
    小程序踩过的一个小坑---解析二维码decodeURIComponent() url解码
    js json转url参数
    微信小程序-实现分享(带参数)
    php中的匿名函数和闭包(closure)
    微信小程序之回调函数
    php AES cbc模式 pkcs7 128位加密解密(微信小程序)
    微信小程序,开发中几个重要的知识点(加密解密,转发,进入场景,session_key)
  • 原文地址:https://www.cnblogs.com/shangyu/p/3796693.html
Copyright © 2011-2022 走看看