zoukankan      html  css  js  c++  java
  • 维修数列 Splay(这可能是我写过最麻烦的题之一了。。。用平衡树维护dp。。。丧心病狂啊。。。。)

    题目来源BZOJ1500

    这题的思路:

    1、这题的话,稍微会splay的人,一般前面四个都不是问题。。主要是最后的一个,要你在修改的同时要维护好最大字段和。。。

    2、最大字段和其实就是区间合并。具体操作可以看POJ2750,这是这道题的简化版本。

    3、然后这题就是三个区间合并嘛。。。慢慢讨论就好了。。。这题写了我一天的时间。。从吃完午饭一直写到了晚上8点才AC。。。

    直接贴代码吧。。这题是我为了学LCT,所以想做做Splay的题先熟悉一下Splay。。。结果选了这个BOSS题。。。心理阴影。。。。

    我觉得我pushup那段写的挺清楚的23333   思路可以看我的pushup和pushdown函数的代码,应该挺好懂的

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<stack>
      5  
      6 using namespace std;
      7  
      8 const int N=500005,INF=0x3f3f3f3f;
      9  
     10 struct Splay_Tree
     11 {
     12     struct Node
     13     {
     14         int val,sum,cover,Size,son[2],mxl,mxr,mx;
     15         bool rev,cov;
     16         void init(int _val)
     17         {
     18             val=sum=mxl=mxr=mx=_val;
     19             Size=1;
     20             rev=cov=cover=son[0]=son[1]=0;
     21         }
     22     } T[N];
     23     stack<int>mem;
     24     int fa[N],root,tot;
     25  
     26     void pushDown(int x)///下放标记(序列操作)
     27     {
     28         if(x==0)return ;
     29         if(T[x].cov)
     30         {
     31             if(T[x].son[0])
     32             {
     33                 T[T[x].son[0]].cov=1;
     34                 T[T[x].son[0]].cover=T[T[x].son[0]].val=T[x].cover;
     35                 T[T[x].son[0]].sum=T[x].cover*T[T[x].son[0]].Size;
     36                 T[T[x].son[0]].rev=0;
     37                 if(T[x].cover>=0)
     38                     T[T[x].son[0]].mx=T[T[x].son[0]].mxl=T[T[x].son[0]].mxr=T[x].cover*T[T[x].son[0]].Size;
     39                 else
     40                     T[T[x].son[0]].mx=T[T[x].son[0]].mxl=T[T[x].son[0]].mxr=T[x].cover;
     41             }
     42             if(T[x].son[1])
     43             {
     44                 T[T[x].son[1]].cov=1;
     45                 T[T[x].son[1]].cover=T[T[x].son[1]].val=T[x].cover;
     46                 T[T[x].son[1]].sum=T[x].cover*T[T[x].son[1]].Size;
     47                 T[T[x].son[1]].rev=0;
     48                 if(T[x].cover>=0)
     49                     T[T[x].son[1]].mx=T[T[x].son[1]].mxl=T[T[x].son[1]].mxr=T[x].cover*T[T[x].son[1]].Size;
     50                 else
     51                     T[T[x].son[1]].mx=T[T[x].son[1]].mxl=T[T[x].son[1]].mxr=T[x].cover;
     52             }
     53             T[x].cov=T[x].cover=T[x].rev=0;
     54         }
     55         if(T[x].rev)
     56         {
     57             if(T[x].son[0])
     58             {
     59                 T[T[x].son[0]].rev^=1;
     60                 swap(T[T[x].son[0]].mxl,T[T[x].son[0]].mxr);
     61             }
     62             if(T[x].son[1])
     63             {
     64                 T[T[x].son[1]].rev^=1;
     65                 swap(T[T[x].son[1]].mxl,T[T[x].son[1]].mxr);
     66             }
     67             swap(T[x].son[0],T[x].son[1]);
     68             T[x].rev=0;
     69         }
     70     }
     71  
     72     void pushUp(int x)///更新节点(序列操作)
     73     {
     74         T[x].Size=1;
     75         T[x].sum=T[x].val;
     76         if(T[x].son[0])
     77             T[x].sum+=T[T[x].son[0]].sum,T[x].Size+=T[T[x].son[0]].Size;
     78         if(T[x].son[1])
     79             T[x].sum+=T[T[x].son[1]].sum,T[x].Size+=T[T[x].son[1]].Size;
     80  
     81         if(T[x].son[0]&&T[x].son[1])
     82         {
     83             T[x].mx=T[x].val;
     84             T[x].mx=max(T[x].mx,T[T[x].son[0]].mx);
     85             T[x].mx=max(T[x].mx,T[T[x].son[1]].mx);
     86             T[x].mx=max(T[x].mx,T[T[x].son[0]].mxr+T[x].val+T[T[x].son[1]].mxl);
     87             T[x].mx=max(T[x].mx,T[x].val+T[T[x].son[0]].mxr);
     88             T[x].mx=max(T[x].mx,T[x].val+T[T[x].son[1]].mxl);
     89  
     90             T[x].mxl=T[T[x].son[0]].mxl;
     91             T[x].mxl=max(T[x].mxl,T[T[x].son[0]].sum+T[x].val);
     92             T[x].mxl=max(T[x].mxl,T[T[x].son[0]].sum+T[x].val+T[T[x].son[1]].mxl);
     93  
     94             T[x].mxr=T[T[x].son[1]].mxr;
     95             T[x].mxr=max(T[x].mxr,T[T[x].son[1]].sum+T[x].val);
     96             T[x].mxr=max(T[x].mxr,T[T[x].son[1]].sum+T[x].val+T[T[x].son[0]].mxr);
     97         }
     98         else if(T[x].son[0]&&!T[x].son[1])
     99         {
    100             T[x].mx=max(T[T[x].son[0]].mxr+T[x].val,T[T[x].son[0]].mx);
    101  
    102             T[x].mx=max(T[x].mx,T[x].val);
    103  
    104             T[x].mxl=max(T[T[x].son[0]].mxl,T[T[x].son[0]].sum+T[x].val);
    105  
    106             T[x].mxr=max(T[x].val,T[x].val+T[T[x].son[0]].mxr);
    107         }
    108         else if(!T[x].son[0]&&T[x].son[1])
    109         {
    110             T[x].mx=max(T[T[x].son[1]].mxl+T[x].val,T[T[x].son[1]].mx);
    111  
    112             T[x].mx=max(T[x].mx,T[x].val);
    113  
    114             T[x].mxl=max(T[x].val,T[x].val+T[T[x].son[1]].mxl);
    115  
    116             T[x].mxr=max(T[T[x].son[1]].mxr,T[T[x].son[1]].sum+T[x].val);
    117         }
    118         else T[x].mxl=T[x].mxr=T[x].mx=T[x].val;
    119  
    120     }
    121  
    122     /*inline void up(int x)///更新节点(普通平衡树操作)
    123     {
    124         T[x].Size=1;
    125         if(T[x].son[0])
    126             T[x].Size+=T[T[x].son[0]].Size;
    127         if(T[x].son[1])
    128             T[x].Size+=T[T[x].son[1]].Size;
    129     }*/
    130  
    131     void Rotate(int x,int kind)///旋转,有左旋右旋(反正配合splay用就好了233)
    132     {
    133         int y=fa[x],z=fa[y];
    134         T[y].son[!kind]=T[x].son[kind],fa[T[x].son[kind]]=y;
    135         T[x].son[kind]=y,fa[y]=x;
    136         T[z].son[T[z].son[1]==y]=x,fa[x]=z;
    137         pushUp(y);
    138     }
    139  
    140     void Splay(int x,int goal)///把下标为x的元素旋转到目标的儿子节点
    141     {
    142         if(x==goal)return ;
    143         while(fa[x]!=goal)
    144         {
    145             int y=fa[x],z=fa[y];
    146             pushDown(z),pushDown(y),pushDown(x);
    147             int rx=T[y].son[0]==x,ry=T[z].son[0]==y;
    148             if(z==goal)Rotate(x,rx);
    149             else
    150             {
    151                 if(rx==ry)Rotate(y,ry);
    152                 else Rotate(x,rx);
    153                 Rotate(x,ry);
    154             }
    155         }
    156         pushUp(x);
    157         if(goal==0)root=x;
    158     }
    159  
    160     int Select(int pos)///查找第k小元素
    161     {
    162         pos--;
    163         int u=root;
    164         pushDown(u);
    165         while(T[T[u].son[0]].Size!=pos)
    166         {
    167             if(pos<T[T[u].son[0]].Size)u=T[u].son[0];
    168             else
    169             {
    170                 pos-=T[T[u].son[0]].Size+1;
    171                 u=T[u].son[1];
    172             }
    173             pushDown(u);
    174         }
    175         return u;
    176     }
    177  
    178  
    179     void Reverse(int L,int R)///序列操作的区间翻转
    180     {
    181         if(L>R)return ;
    182         int u=Select(L-1),v=Select(R+1);
    183         Splay(u,0);
    184         Splay(v,u);
    185         T[T[v].son[0]].rev^=1;
    186         swap(T[T[v].son[0]].mxl,T[T[v].son[0]].mxr);
    187         pushDown(T[v].son[0]);
    188         update(T[v].son[0]);
    189     }
    190  
    191     void Cover(int L,int R,int Val)///序列操作的区间翻转
    192     {
    193         if(L>R)return ;
    194         int u=Select(L-1),v=Select(R+1);
    195         Splay(u,0);
    196         Splay(v,u);
    197         T[T[v].son[0]].cov=1;
    198         T[T[v].son[0]].cover=T[T[v].son[0]].val=Val;
    199         pushDown(T[v].son[0]);
    200         update(T[v].son[0]);
    201     }
    202  
    203     int build(int L,int R,int *a)///区间操作建树
    204     {
    205         if(L>R)return 0;
    206         int mid=(L+R)>>1,sL,sR;
    207         int loc=mem.top();mem.pop();
    208         T[loc].init(a[mid]);
    209         if(L==R)return loc;
    210         T[loc].son[0]=sL=build(L,mid-1,a);
    211         T[loc].son[1]=sR=build(mid+1,R,a);
    212         fa[sL]=fa[sR]=loc;
    213         pushUp(loc);
    214         return loc;
    215     }
    216  
    217     void init(int n,int *a)///区间操作,输入n个元素建树
    218     {
    219         T[0].init(INF);
    220         for(int i=500001;i>=1;i--)
    221             mem.push(i);
    222         root=build(1,n,a),fa[root]=0;
    223         fa[0]=0,T[0].son[1]=root,T[0].Size=0;
    224     }
    225  
    226     void Insert(int pos,int n,int *a)
    227     {
    228         if(n==0)return ;
    229         int u=Select(pos-1),v=Select(pos);
    230         Splay(u,0);
    231         Splay(v,u);
    232         fa[T[v].son[0]=build(1,n,a)]=v;
    233         update(T[v].son[0]);
    234     }
    235  
    236     void Delete(int L,int R)
    237     {
    238         if(L>R)return ;
    239         int u=Select(L-1),v=Select(R+1);
    240         Splay(u,0);
    241         Splay(v,u);
    242         Free(T[v].son[0]);
    243         T[v].son[0]=0;
    244         update(v);
    245     }
    246  
    247     int Get_sum(int L,int R)
    248     {
    249         if(L>R)return 0;
    250         int u=Select(L-1),v=Select(R+1);
    251         Splay(u,0);
    252         Splay(v,u);
    253         if(T[v].son[0])
    254             return T[T[v].son[0]].sum;
    255         else return 0;
    256     }
    257  
    258     int Get_max(int L,int R)
    259     {
    260         if(L>R)return 0;
    261         int u=Select(L-1),v=Select(R+1);
    262         Splay(u,0);
    263         Splay(v,u);
    264         if(T[v].son[0])
    265             return T[T[v].son[0]].mx;
    266         else return 0;
    267     }
    268  
    269     void Free(int x)
    270     {
    271         if(x==0)return ;
    272         Free(T[x].son[0]);
    273         mem.push(x);
    274         Free(T[x].son[1]);
    275     }
    276  
    277     /*void Insert(int &t,int val,int par=0)///普通平衡树,往某个地方的下面插入元素,一般是插入根节点
    278     {
    279         if(t==0)
    280         {
    281             t=++tot;
    282             T[t].init(val);
    283             fa[t]=par;
    284             Splay(tot,0);
    285         }
    286         else
    287         {
    288             int cur=t;
    289             if(val<T[t].val)Insert(T[t].son[0],val,cur);
    290             //else if(val==T[t].val)return ;
    291             else Insert(T[t].son[1],val,cur);
    292             up(cur);
    293         }
    294     }*/
    295  
    296     /*int find(int t,int v)///普通平衡树查找值为v的元素
    297     {
    298         if(t==0)return 0;
    299         else if(T[t].val==v)
    300         {
    301             Splay(t,0);
    302             return t;
    303         }
    304         else if(v<T[t].val)return find(T[t].son[0],v);
    305         else return find(T[t].son[1],v);
    306     }*/
    307  
    308     ///删除根节点元素
    309     /*void Delete()
    310     {
    311         if(!T[root].son[0])
    312         {
    313             fa[T[root].son[1]]=0;
    314             root=T[root].son[1];
    315         }
    316         else
    317         {
    318             int cur=T[root].son[0];
    319             while(T[cur].son[1])cur=T[cur].son[1];
    320             Splay(cur,root);
    321             T[cur].son[1]=T[root].son[1];
    322             root=cur,fa[cur]=0,fa[T[root].son[1]]=root;
    323             up(root);
    324         }
    325     }*/
    326  
    327     int size()
    328     {
    329         return T[root].Size;
    330     }
    331  
    332     ///从t开始找值为v的前驱,返回值
    333     int pred(int t,int v)
    334     {
    335         if(t==0)return v;
    336         else
    337         {
    338             if(v<=T[t].val)return pred(T[t].son[0],v);
    339             else
    340             {
    341                 int ans=pred(T[t].son[1],v);
    342                 if(ans==v)
    343                     ans=T[t].val,Splay(t,0);
    344                 return ans;
    345             }
    346         }
    347     }
    348     ///查找下标t节点的前驱返回下标
    349     int pred(int t)
    350     {
    351         Splay(t,0);
    352         int u=T[t].son[0];
    353         if(u==0)return fa[t];
    354         while(T[u].son[1])u=T[u].son[1];
    355         return u;
    356     }
    357  
    358     ///从t开始找值为v的后继,返回值
    359     int succ(int t,int v)
    360     {
    361         if(t==0)return v;
    362         else
    363         {
    364             if(v>=T[t].val)return succ(T[t].son[1],v);
    365             else
    366             {
    367                 int ans=succ(T[t].son[0],v);
    368                 if(ans==v)
    369                     ans=T[t].val,Splay(t,0);
    370                 return ans;
    371             }
    372         }
    373     }
    374  
    375     ///查找下标t节点的后继返回下标
    376     int succ(int t)
    377     {
    378         Splay(t,0);
    379         int u=T[t].son[1];
    380         if(u==0)return fa[t];
    381         while(T[u].son[0])u=T[u].son[0];
    382         return u;
    383     }
    384  
    385     void Preorder( int t ){///输出成序列顺便检查是否有逻辑错误
    386         if( !t ) return;
    387         pushDown(t);
    388         Preorder( T[t].son[0] );
    389         if(T[t].son[0]&&fa[T[t].son[0]]!=t)
    390             printf("!");
    391         printf("%d " , T[t].val );
    392         Preorder( T[t].son[1] );
    393     }
    394  
    395     /*void init()///普通平衡树初始化
    396     {
    397         T[0].init(-INF);
    398         tot=root=0;
    399     }*/
    400  
    401     void update(int x)///更新下标为x的节点。。手动操作后调用
    402     {
    403         while(x!=0)
    404         pushUp(x),x=fa[x];
    405     }
    406  
    407 };
    408  
    409 Splay_Tree tree;
    410  
    411 int a[N];
    412  
    413 char str[22];
    414  
    415 int main()
    416 {
    417     int n,m;
    418     scanf("%d%d",&n,&m);
    419     for(int i=2;i<=n+1;i++)
    420         scanf("%d",a+i);
    421     tree.init(n+2,a);
    422     int sum=n;
    423     while(m--)
    424     {
    425         scanf("%s",str+1);
    426         if(str[3]=='S')
    427         {
    428             int pos,tot;
    429             scanf("%d%d",&pos,&tot);
    430             pos++;
    431             pos++;
    432             sum+=tot;
    433             for(int i=1;i<=tot;i++)
    434                 scanf("%d",a+i);
    435             tree.Insert(pos,tot,a);
    436         }
    437         else if(str[3]=='L')
    438         {
    439             int pos,tot;
    440             scanf("%d%d",&pos,&tot);
    441             pos++;
    442             tree.Delete(pos,pos+tot-1);
    443             sum-=tot;
    444         }
    445         else if(str[3]=='K')
    446         {
    447             int pos,tot,cov;
    448             scanf("%d%d%d",&pos,&tot,&cov);
    449             pos++;
    450             tree.Cover(pos,pos+tot-1,cov);
    451         }
    452         else if(str[3]=='V')
    453         {
    454             int pos,tot;
    455             scanf("%d%d",&pos,&tot);
    456             pos++;
    457             tree.Reverse(pos,pos+tot-1);
    458         }
    459         else if(str[3]=='T')
    460         {
    461             int pos,tot;
    462             scanf("%d%d",&pos,&tot);
    463             pos++;
    464             printf("%d
    ",tree.Get_sum(pos,pos+tot-1));
    465         }
    466         if(str[3]=='X')
    467         {
    468             printf("%d
    ",tree.Get_max(2,tree.size()-1));
    469         }
    470     }
    471     return 0;
    472 }
    473 
    View Code
  • 相关阅读:
    CF1202F You Are Given Some Letters...
    CF1178E Archaeology
    PTA (Advanced Level) 1005 Spell It Right
    PTA (Advanced Level) 1004 Counting Leaves
    Qt5——从零开始的Hello World教程(Qt Creator)
    PTA (Advanced Level) 1003 Emergency
    PTA (Advanced Level) 1002 A+B for Polynomials
    HDU 1272 小希的迷宫
    FZU 2150 Fire Game
    HihoCoder
  • 原文地址:https://www.cnblogs.com/xseventh/p/8585828.html
Copyright © 2011-2022 走看看