zoukankan      html  css  js  c++  java
  • 一练Splay之维修数列第一次

    平衡树并不是之前没写过,觉得有必要把平衡树变成考场上能敲的东西,也就是说,考一道诸如“维修数列”这样的送分题,要能拿满分。

    维修数列。给定一个数列支持以下操作:

    输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
    第2行包含N个数字,描述初始时的数列。
    以下M行,每行一条命令,格式参见问题描述中的表格。
    任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
    插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

    以上都是复制的。

    这一次呢肯定比上一次敲的快了那么一点,但没有达到要求,总时间大概3h,还需很大的提升。

    调试时间。。inf

    主要的调试时间在边界的处理上。

    1、某个子树大小。本来子树大小如果不影响答案计算的话是可以直接把边界加进来的,但是这里有求和和区间赋值,因此有必要知道区间除了边界外的真实大小。

    这一次的处理方式是:假设边界点是不存在的,即size=0.这样引发的一系列调整如下:

    首先,up时size的更新要注意不要加上边界点:

    a[x].size=a[p].size+a[q].size+(x!=lbod && x!=rbod);

    其次,find时对边界点单独处理下:

            if (K>a[root].size) ans=rbod;
            else if (K==0) ans=lbod;

    在find时,找第K个数,如果往右走要这么写:

    K-=a[x].size-a[a[x].son[1]].size,x=a[x].son[1];

    而不要写K-=a[a[x].son[0]].size+1,这样相当于默认x的size是1,而x有可能是边界点。

    2、连边必up,访子必down。up和down在一些细节会忘了打。最典型的是splay:splay(x,top)表示把x旋到top下,如果top不为0的话应up(top);再如find以及其他类似操作时心存侥幸以为不用down,但实际上这题有区间翻转操作,左右儿子会变,因此必须down。

    3、读入。注意'-'号。

    4、答案。注意边界点既要做到能传递区间答案,本身又不能对答案产生影响。这里解决的方法是在up的时候进行如下判断:

            if (x!=lbod && x!=rbod) a[x].Maxsum=max(a[p].Maxsum,max(a[q].Maxsum,a[p].rsum+a[x].v+a[q].lsum));
            else if (x==lbod) a[x].Maxsum=q?a[q].Maxsum:-0x3f3f3f3f;
            else a[x].Maxsum=p?a[p].Maxsum:-0x3f3f3f3f;

    以及在区间赋值时进行如下操作:

            if (x==lbod || x==rbod) a[x].v=0;
            if (a[x].size==0) a[x].lsum=a[x].rsum=a[x].Maxsum=-0x3f3f3f3f;

    调试时果断选择区间输出。但静态查错还是不能少。

    总的来说,有待提高。

      1 #include<string.h>
      2 #include<stdlib.h>
      3 #include<stdio.h>
      4 //#include<assert.h>
      5 #include<algorithm>
      6 //#include<iostream>
      7 using namespace std;
      8 
      9 int n,m;
     10 #define maxn 500011
     11 int num[maxn];
     12 
     13 struct Splay
     14 {
     15     struct Node
     16     {
     17         int son[2],fa;
     18         bool rev,hbe; int be;
     19         int v,size,sum,Maxsum,lsum,rsum;
     20     }a[maxn];
     21     int root,sta[maxn],top,lbod,rbod;
     22     Splay()
     23     {
     24         top=500000;
     25         for (int i=1;i<=top;i++) sta[i]=i;
     26         root=lbod=500001; rbod=500002;
     27         a[0].Maxsum=-0x3f3f3f3f;
     28         a[lbod].Maxsum=a[rbod].Maxsum=a[lbod].lsum=a[lbod].rsum=a[rbod].lsum=a[rbod].rsum=-0x3f3f3f3f;
     29         a[lbod].v=a[lbod].size=a[lbod].sum=a[lbod].rev=a[lbod].hbe=0;
     30         a[rbod].v=a[rbod].size=a[rbod].sum=a[rbod].rev=a[rbod].hbe=0;
     31         a[lbod].son[1]=rbod; a[rbod].fa=lbod;
     32     }
     33     void up(int x)
     34     {
     35         if (!x) return;
     36         int &p=a[x].son[0],&q=a[x].son[1];
     37         a[x].sum=a[p].sum+a[q].sum+a[x].v;
     38         a[x].size=a[p].size+a[q].size+(x!=lbod && x!=rbod);
     39         if (x!=lbod && x!=rbod) a[x].Maxsum=max(a[p].Maxsum,max(a[q].Maxsum,a[p].rsum+a[x].v+a[q].lsum));
     40         else if (x==lbod) a[x].Maxsum=q?a[q].Maxsum:-0x3f3f3f3f;
     41         else a[x].Maxsum=p?a[p].Maxsum:-0x3f3f3f3f;
     42         a[x].lsum=max(a[p].lsum,a[p].sum+a[x].v+a[q].lsum);
     43         a[x].rsum=max(a[q].rsum,a[q].sum+a[x].v+a[p].rsum);
     44     }
     45     void besingle(int x,int v)
     46     {
     47         if (!x) return;
     48         a[x].v=a[x].be=v; a[x].hbe=1;
     49         if (x==lbod || x==rbod) a[x].v=0;
     50         a[x].sum=a[x].size*v;
     51         if (v>=0) a[x].lsum=a[x].rsum=a[x].Maxsum=a[x].sum;
     52         else a[x].lsum=a[x].rsum=0,a[x].Maxsum=v;
     53         if (a[x].size==0) a[x].lsum=a[x].rsum=a[x].Maxsum=-0x3f3f3f3f;
     54     }
     55     void revsingle(int x)
     56     {
     57         if (!x) return;
     58         a[x].rev^=1; int t=a[x].son[0]; a[x].son[0]=a[x].son[1]; a[x].son[1]=t;
     59         t=a[x].lsum; a[x].lsum=a[x].rsum; a[x].rsum=t;
     60     }
     61     void down(int x)
     62     {
     63         int &p=a[x].son[0],&q=a[x].son[1];
     64         if (a[x].hbe) {besingle(p,a[x].be); besingle(q,a[x].be); a[x].hbe=0;}
     65         if (a[x].rev) {revsingle(p); revsingle(q); a[x].rev=0;}
     66     }
     67     int dsta[maxn],dtop;
     68     void download(int x)
     69     {
     70         dtop=0;
     71         for (int i=x;i;i=a[i].fa) dsta[++dtop]=i;
     72         while (dtop) down(dsta[dtop--]);
     73     }
     74     void rotate(int x)
     75     {
     76         const int y=a[x].fa,z=a[y].fa;
     77         bool w=(x==a[y].son[0]);
     78         a[x].fa=z;
     79         if (z) a[z].son[y==a[z].son[1]]=x;
     80         a[y].son[w^1]=a[x].son[w];
     81         if (a[x].son[w]) a[a[x].son[w]].fa=y;
     82         a[x].son[w]=y;
     83         a[y].fa=x;
     84         up(y); up(z);
     85     }
     86     void splay(int x,int top)
     87     {
     88         if (!x) return;
     89         download(x);
     90         while (a[x].fa!=top)
     91         {
     92             const int y=a[x].fa,z=a[y].fa;
     93             if (z!=top)
     94             {
     95                 if ((x==a[y].son[0])^(y==a[z].son[0])) rotate(x);
     96                 else rotate(y);
     97             }
     98             rotate(x);
     99         }
    100         up(x);
    101         if (!top) root=x; else up(top);
    102     }
    103     int find(int K)
    104     {
    105 //        cout<<K<<endl;
    106         int x=root,ans=0;
    107         if (K>a[root].size) ans=rbod;
    108         else if (K==0) ans=lbod;
    109         else while (x)
    110         {
    111 //            cout<<x<<' '<<K<<endl;
    112             down(x);
    113             if (x==lbod) x=a[x].son[1];
    114             else if (x==rbod) x=a[x].son[0];
    115             else if (a[a[x].son[0]].size<K-1) K-=a[x].size-a[a[x].son[1]].size,x=a[x].son[1];
    116             else ans=x,x=a[x].son[0];
    117         }
    118         if (ans) splay(ans,0);
    119         return ans;
    120     }
    121     void New(int &x) {x=sta[top--];}
    122     void build(int &x,int L,int R)
    123     {
    124         if (L>R) {x=0; return;}
    125         New(x);
    126 //        cout<<x<<' '<<L<<' '<<R<<endl;
    127         const int mid=(L+R)>>1;
    128         a[x].v=a[x].sum=a[x].Maxsum=num[mid]; a[x].size=1; a[x].hbe=a[x].rev=0;
    129         if (num[mid]>=0) a[x].lsum=a[x].rsum=num[mid];
    130         else a[x].lsum=a[x].rsum=0;
    131         build(a[x].son[0],L,mid-1);
    132         if (a[x].son[0]) a[a[x].son[0]].fa=x;
    133         build(a[x].son[1],mid+1,R);
    134         if (a[x].son[1]) a[a[x].son[1]].fa=x;
    135         up(x);
    136     }
    137     void build(int &x,int n) {build(x,1,n);}
    138     void insert(int pos,int tot)
    139     {
    140         int x=find(pos),y=a[x].son[1];
    141 //        cout<<x<<' '<<y<<endl;
    142         while (a[y].son[0]) down(y),y=a[y].son[0];
    143         splay(y,x);
    144         build(a[y].son[0],tot);
    145         a[a[y].son[0]].fa=y;
    146         up(y); up(x);
    147     }
    148     void recycle(int x)
    149     {
    150         sta[++top]=x;
    151         if (a[x].son[0]) recycle(a[x].son[0]);
    152         if (a[x].son[1]) recycle(a[x].son[1]);
    153     }
    154     void Delete(int pos,int tot)
    155     {
    156         int y=find(pos+tot);
    157 //        test();
    158         int x=find(pos-1);
    159 //        test();
    160         splay(y,x);
    161         if (a[y].son[0]) recycle(a[y].son[0]);
    162         a[y].son[0]=0; up(y); up(x);
    163     }
    164     void Be(int pos,int tot,int v)
    165     {
    166         int y=find(pos+tot),x=find(pos-1);
    167         splay(y,x);
    168         besingle(a[y].son[0],v);
    169         up(y); up(x);
    170     }
    171     void Rev(int pos,int tot)
    172     {
    173         int y=find(pos+tot),x=find(pos-1);
    174         splay(y,x);
    175         revsingle(a[y].son[0]);
    176         up(y); up(x);
    177     }
    178     int Sum(int pos,int tot)
    179     {
    180 //        cout<<pos<<' '<<tot<<endl;
    181         int y=find(pos+tot);
    182 //        test();
    183         int x=find(pos-1);
    184 //        test();
    185         splay(y,x);
    186         return a[a[y].son[0]].sum;
    187     }
    188     int Maxsum() {return a[root].Maxsum;}
    189 //    void test(int x)
    190 //    {
    191 //        if (!x) return;
    192 ////        down(x);
    193 //        test(a[x].son[0]);
    194 //        cout<<x<<' '<<a[x].v<<" size"<<a[x].size<<" sum"<<a[x].sum<<" Maxsum"<<a[x].Maxsum
    195 //        <<" lsum"<<a[x].lsum<<" rsum"<<a[x].rsum<<" son0 "<<a[x].son[0]<<" son1 "<<a[x].son[1]
    196 //        <<" be"<<a[x].be<<" rev"<<a[x].rev<<endl;
    197 //        test(a[x].son[1]);
    198 //    }
    199 //    void test() {test(root);cout<<endl;}
    200 }t;
    201 
    202 int qread()
    203 {
    204     char c;int s=0,t=1; while ((c=getchar())<'0' || c>'9') (c=='-' && (t=-1));
    205     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*t;
    206 }
    207 int main()
    208 {
    209     n=qread(); m=qread();
    210     for (int i=1;i<=n;i++) num[i]=qread();
    211     t.insert(0,n);
    212 //    t.test();
    213     char c;
    214     for (int i=1,x,y,z;i<=m;i++)
    215     {
    216 //        cout<<i<<"!!!"<<t.a[t.root].size<<' '<<t.a[0].size<<endl;
    217         while ((c=getchar())<'A' || c>'Z');
    218         if (c=='I')
    219         {
    220             while (((c=getchar())>='A' && c<='Z') || c=='-');
    221             x=qread(); y=qread();
    222             for (int j=1;j<=y;j++) num[j]=qread();
    223             t.insert(x,y);
    224         }
    225         else if (c=='D')
    226         {
    227             while (((c=getchar())>='A' && c<='Z') || c=='-');
    228             x=qread(); y=qread();
    229             t.Delete(x,y);
    230         }
    231         else if (c=='R')
    232         {
    233             while (((c=getchar())>='A' && c<='Z') || c=='-');
    234             x=qread(); y=qread();
    235             t.Rev(x,y);
    236         }
    237         else if (c=='G')
    238         {
    239             while (((c=getchar())>='A' && c<='Z') || c=='-');
    240             x=qread(); y=qread();
    241             printf("%d
    ",t.Sum(x,y));
    242         }
    243         else
    244         {
    245             c=getchar(); c=getchar();
    246             if (c=='K')
    247             {
    248                 while (((c=getchar())>='A' && c<='Z') || c=='-');
    249                 x=qread(); y=qread(); z=qread();
    250                 t.Be(x,y,z);
    251             }
    252             else
    253             {
    254                 while (((c=getchar())>='A' && c<='Z') || c=='-');
    255                 printf("%d
    ",t.Maxsum());
    256             }
    257         }
    258 //        t.up(t.lbod);
    259 //        t.test();
    260     }
    261     return 0;
    262 }
    View Code
  • 相关阅读:
    容器级虚拟化如何进行资源分配
    容器虚拟化实现的原理
    tensorflow报cudnn错误
    nginx调优
    mysql主从原理及配置
    新安装mysql,如何提升mysql安全性
    LINUX系统软件安装和卸载的常见方法
    如何增加黑客通过ssh入侵的难度--保护ssh的三把锁
    ubuntu-docker入门到放弃(八)创建支持SSH服务的镜像
    ubuntu-docker入门到放弃(七)操作系统
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8253133.html
Copyright © 2011-2022 走看看