zoukankan      html  css  js  c++  java
  • NOI2005维修数列(splay)

    题目描述:

    Description

    请写一个程序,要求维护一个数列,支持以下 6 种操作:
    请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格

    Input

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

    Output

    对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

    Sample Input

    9 8
    2 -6 3 5 1 -5 -3 6 3
    GET-SUM 5 4
    MAX-SUM
    INSERT 8 3 -5 7 2
    DELETE 12 1
    MAKE-SAME 3 3 2
    REVERSE 3 6
    GET-SUM 5 4
    MAX-SUM

    Sample Output

    -1
    10
    1
    10

     

    解题思路:

    听说出这道题时还没有splay,所以当时是块状链表题。

    6种操作:

    1.插入:

    常规操作,将子树建好再把前驱后继中间空出来栽上,pushup两遍愈合即可。

    PS:可以用建树时的build函数适配数组

    2.删除:

    将整棵树像挤痘痘一样挤出来扔掉。

    PS:空间开不下,需要回收废树,不要将树分解,那样浪费时间,开一个栈,将废树压入,开新点时弹出一棵树,推入左右子树,根节点格式化输出即可。

    3.修改:

    常规操作,只不过用bool做懒惰标记主要是我怕它区间赋0

    4.翻转:

    文艺平衡树模板。

    PS:pushdown时若有3的bool型标记就可以清除4的标记了。

    5.求和:

    维护一个sum

    6.最大值:

    类似vijos小白逛公园维护左连续最大值,右连续最大值,中间连续最大值即可。

    PS:把0号节点的中间连续最大值赋为-,防止ans<0

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll tr[spc].ch[0]
      5 #define rrr tr[spc].ch[1]
      6 #define ls ch[0]
      7 #define rs ch[1]
      8 const int N=6000001;
      9 struct trnt{
     10     int ch[2];
     11     int fa;
     12     bool onmi;
     13     int lzt;
     14     int val;
     15     int sum;
     16     int wgt;
     17     int lmx,rmx,mmx;
     18     int chd;
     19 }tr[N];
     20 trnt stdtr;
     21 int n,m;
     22 int lne[N];
     23 int bin[N];
     24 int top=0;
     25 int root;
     26 int siz;
     27 char cmd[100];
     28 int ins[N];
     29 int org,fin;
     30 void destory(int &spc)
     31 {
     32     bin[++top]=spc;
     33     spc=0;
     34     return ;
     35 }
     36 int translate(void)
     37 {
     38     int tmp=(int)(cmd[2]);
     39     if(tmp=='S')
     40         return 1;
     41     if(tmp=='L')
     42         return 2;
     43     if(tmp=='K')
     44         return 3;
     45     if(tmp=='V')
     46         return 4;
     47     if(tmp=='T')
     48         return 5;
     49     if(tmp=='X')
     50         return 6;
     51        return 0;
     52 }
     53 bool whc(int spc)
     54 {
     55     return tr[tr[spc].fa].rs==spc;
     56 }
     57 void pushup(int spc)
     58 {
     59     tr[spc].sum=tr[lll].sum+tr[rrr].sum+tr[spc].val;
     60     tr[spc].wgt=tr[lll].wgt+tr[rrr].wgt+1;
     61     tr[spc].lmx=std::max(tr[lll].lmx,tr[lll].sum+tr[spc].val+tr[rrr].lmx);
     62     tr[spc].rmx=std::max(tr[rrr].rmx,tr[rrr].sum+tr[spc].val+tr[lll].rmx);
     63     tr[spc].mmx=std::max(tr[spc].val+tr[lll].rmx+tr[rrr].lmx,std::max(tr[lll].mmx,tr[rrr].mmx));
     64     return ;
     65 }
     66 int apply()
     67 {
     68     if(top)
     69     {
     70         int spc=bin[top--];
     71         if(lll)
     72             bin[++top]=lll;
     73         if(rrr)
     74             bin[++top]=rrr;
     75         return spc;
     76     }
     77     return ++siz;
     78 }
     79 void address(int &spc)
     80 {
     81     spc=apply();
     82     tr[spc]=stdtr;
     83     return ;
     84 }
     85 void new_point(int &spc,int mid,int *a,int f)
     86 {
     87     address(spc);
     88     tr[spc].fa=f;
     89     tr[spc].val=a[mid];
     90     return ;
     91 }
     92 void din(int spc,int k)
     93 {
     94     if(!spc)
     95         return ;
     96     tr[spc].onmi=true;
     97     tr[spc].lzt=k;
     98     tr[spc].val=k;
     99     tr[spc].sum=tr[spc].wgt*k;
    100     tr[spc].mmx=(k>0)?tr[spc].sum:k;
    101     tr[spc].lmx=tr[spc].rmx=(k>0)?tr[spc].sum:0;
    102     return ;
    103 }
    104 void ovt(int spc)
    105 {
    106     if(!spc)
    107         return ;
    108     tr[spc].chd^=1;
    109     std::swap(lll,rrr);
    110     std::swap(tr[spc].lmx,tr[spc].rmx);
    111     return ;
    112 }
    113 void pushdown(int spc)
    114 {
    115     if(tr[spc].onmi)
    116     {
    117         din(lll,tr[spc].lzt);
    118         din(rrr,tr[spc].lzt);
    119         tr[spc].lzt=0;
    120         tr[spc].chd=0;
    121         tr[spc].onmi=false;
    122     }
    123     if(tr[spc].chd)
    124     {
    125         ovt(lll);
    126         ovt(rrr);
    127         tr[spc].chd=0;
    128     }
    129     return ;
    130 }
    131 void rotate(int spc)
    132 {
    133     int f=tr[spc].fa;
    134     bool k=whc(spc);
    135     tr[f].ch[k]=tr[spc].ch[!k];
    136     tr[spc].ch[!k]=f;
    137     tr[tr[f].fa].ch[whc(f)]=spc;
    138     tr[spc].fa=tr[f].fa;
    139     tr[f].fa=spc;
    140     tr[tr[f].ch[k]].fa=f;
    141     pushup(f);
    142     pushup(spc);
    143     return ;
    144 }
    145 void splay(int spc,int f)
    146 {
    147     while(tr[spc].fa!=f)
    148     {
    149         int ft=tr[spc].fa;
    150         if(tr[ft].fa==f)
    151         {
    152             rotate(spc);
    153             break;
    154         }
    155         if(whc(spc)^whc(ft))
    156             rotate(spc);
    157         else
    158             rotate(ft);
    159         rotate(spc);
    160     }
    161     if(!f)
    162         root=spc;
    163     return ;
    164 }
    165 void build(int l,int r,int &spc,int f,int *a)
    166 {
    167     if(l>r)
    168         return ;
    169     int mid=(l+r)>>1;
    170     new_point(spc,mid,a,f);
    171     if(l==r)
    172     {
    173         tr[spc].lmx=tr[spc].rmx=(a[mid]>0)?a[mid]:0;
    174         tr[spc].mmx=a[mid];
    175         tr[spc].wgt=1;
    176         tr[spc].sum=a[mid];
    177         if(l==0)
    178             org=spc;
    179            if(l==n+1)
    180                fin=spc;
    181     }
    182     build(l,mid-1,lll,spc,a);
    183     build(mid+1,r,rrr,spc,a);
    184     pushup(spc);
    185     if(l==r)
    186         tr[spc].mmx=tr[spc].val;
    187     return ;
    188 }
    189 int place(int spc,int rnk)
    190 {
    191     pushdown(spc);
    192     if(tr[lll].wgt>=rnk)
    193         return place(lll,rnk);
    194     if(tr[lll].wgt+1==rnk)
    195         return spc;
    196     return place(rrr,rnk-tr[lll].wgt-1);
    197 }
    198 int main()
    199 {
    200     scanf("%d%d",&n,&m);
    201     for(int i=1;i<=n;i++)
    202         scanf("%d",&lne[i]);
    203     build(0,n+1,root,0,lne);
    204     tr[0].mmx=-0x3f3f3f3f;
    205     while(m--)
    206     {
    207         scanf("%s",cmd);
    208         int opr=translate();
    209         if(opr==1)
    210         {
    211             int tmproot;
    212             int pos,tot;
    213             scanf("%d%d",&pos,&tot);
    214             for(int i=1;i<=tot;i++)
    215                 scanf("%d",&ins[i]);
    216             build(1,tot,tmproot,0,ins);
    217             splay(place(root,pos+1),0);
    218             splay(place(root,pos+2),root);
    219             tr[tr[root].rs].ls=tmproot;
    220             tr[tmproot].fa=tr[root].rs;
    221             pushup(tr[root].rs);
    222             pushup(root);
    223         }else if(opr==2)
    224         {
    225             int pos,tot;
    226             scanf("%d%d",&pos,&tot);
    227             splay(place(root,pos),0);
    228             splay(place(root,pos+tot+1),root);
    229             destory(tr[tr[root].rs].ls);
    230             pushup(tr[root].rs);
    231             pushup(root);
    232         }else if(opr==3)
    233         {
    234             int pos,tot,c;
    235             scanf("%d%d%d",&pos,&tot,&c);
    236             splay(place(root,pos),0);
    237             splay(place(root,pos+tot+1),root);
    238             pushdown(root);
    239             pushdown(tr[root].rs);
    240             int spc=tr[tr[root].rs].ls;
    241             din(spc,c);
    242             pushup(tr[root].rs);
    243             pushup(root);
    244         }else if(opr==4)
    245         {
    246             int pos,tot;
    247             scanf("%d%d",&pos,&tot);
    248             splay(place(root,pos),0);
    249             splay(place(root,pos+tot+1),root);
    250             pushdown(root);
    251             pushdown(tr[root].rs);
    252             int spc=tr[tr[root].rs].ls;
    253             ovt(spc);
    254             pushup(tr[root].rs);
    255             pushup(root);
    256         }else if(opr==5)
    257         {
    258             int pos,tot;
    259             scanf("%d%d",&pos,&tot);
    260             splay(place(root,pos),0);
    261             splay(place(root,pos+tot+1),root);
    262             int spc=tr[tr[root].rs].ls;
    263             printf("%d
    ",tr[spc].sum);
    264         }else{
    265             splay(place(root,1),0);
    266             splay(place(root,tr[root].wgt),root);
    267             printf("%d
    ",tr[tr[tr[root].rs].ls].mmx);
    268         }
    269     }
    270     return 0;
    271 }

  • 相关阅读:
    腾讯安全上海游戏部门笔试题
    2017
    2016
    2015
    2014
    2013
    2012
    2011
    2010
    2009
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9600970.html
Copyright © 2011-2022 走看看