zoukankan      html  css  js  c++  java
  • [NOI2005] 维护数列

    [NOI2005] 维护数列

    题目

    传送门

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

    操作编号

    输入文件中的格式

    说明

    1.  插入

    INSERT_posi_tot_c1_c2_..._ctot

    在当前数列的第 posi 个数字后插入 tot

    个数字:c1, c2, …, ctot;若在数列首插

    入,则 posi 为 0

    2.  删除

    DELETE_posi_tot

    从当前数列的第 posi 个数字开始连续

    删除 tot 个数字

    3.  修改

    MAKE-SAME_posi_tot_c

    将当前数列的第 posi 个数字开始的连

    续 tot 个数字统一修改为 c

    4.  翻转

    REVERSE_posi_tot

    取出从当前数列的第 posi 个数字开始

    的 tot 个数字,翻转后放入原来的位置

    5.  求和

    GET-SUM_posi_tot

    计算从当前数列开始的第 posi 个数字

    开始的 tot 个数字的和并输出

    6.  求和最

    大的子列

    MAX-SUM

    求出当前数列中和最大的一段子列,

    并输出最大和

    INPUT

    输入文件的第 1 行包含两个数 N 和 M,N 表示初始时数列中数的个数,M表示要进行的操作数目。

    第 2 行包含 N 个数字,描述初始时的数列。

    以下 M 行,每行一条命令,格式参见问题描述中的表格。

    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

    OUTPUT

    -1

    10

    1

    10

    解题报告

    做这道题前请做好心理准备= =

    比如说你会看到这样的评论:

    QhelDIV:记得byvoid的博客上说这个题他当时写了整整一天,
    我大约写了8个小时?
    这种长代码程序结构一定要简单简单再简单,否则就是无限的调试了

    Chenyao2333:策爷:“splay/块状链表的自虐题。”。深刻理解到如果没有M倾向就不要去写这题了。。。

    wumingshi:这道题太恶心辣
    一定要处理好哨兵节点和null节点的数据,update时要注意!
    【没有用哨兵节点的请随意

    很裸的SpalySplay板子题,然而并不是那么好打= =

    本来打了256行的数组板子

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 using namespace std;
      5 inline int read(){
      6     int sum(0),f(1);
      7     char ch(getchar());
      8     for(;ch<'0'||ch>'9';ch=getchar())
      9         if(ch=='-')
     10             f=-1;
     11     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     12     return sum*f;
     13 }
     14 int ch[4000001][2],f[4000001],key[4000001],size[4000001];
     15 int sum[4000001],maxl[4000001],maxr[4000001],maxn[4000001];
     16 int root,sz;
     17 bool lazy[4000001],rev[4000001];
     18 inline void clear(int x){
     19     f[x]=ch[x][0]=ch[x][1]=size[x]=key[x]=sum[x]=0;
     20     lazy[x]=rev[x]=maxl[x]=maxr[x]=0;
     21     maxn[x]=-1000000000;
     22 }
     23 inline int get(int x){
     24     return ch[f[x]][1]==x;
     25 }
     26 inline int my_max(int a,int b){
     27     return a>b?a:b;
     28 }
     29 inline void swp(int &a,int &b){
     30     a^=b;
     31     b^=a;
     32     a^=b;
     33 }
     34 inline void update(int x){
     35     int l(ch[x][0]),r(ch[x][1]);
     36     sum[x]=sum[l]+sum[r]+key[x];
     37     size[x]=size[l]+size[r]+1;
     38     maxn[x]=maxl[r]+key[x]+maxr[l];
     39     if(l)
     40         maxn[x]=my_max(maxn[x],maxn[l]);
     41     if(r)
     42         maxn[x]=my_max(maxn[x],maxn[r]);
     43     maxl[x]=my_max(maxl[l],sum[l]+key[x]+maxl[r]);
     44     maxr[x]=my_max(maxr[r],sum[r]+key[x]+maxr[l]);
     45 }
     46 inline void pushdown(int x){
     47     int l(ch[x][0]),r(ch[x][1]);
     48     if(lazy[x]){
     49         rev[x]=lazy[x]=0;
     50         if(l){
     51             lazy[l]=1;
     52             key[l]=key[x];
     53             sum[l]=key[l]*size[l];
     54         }
     55         if(r){
     56             lazy[r]=1;
     57             key[r]=key[x];
     58             sum[r]=key[r]*size[r];
     59         }
     60         if(key[x]>=0){
     61             if(l)
     62                 maxl[l]=maxr[l]=maxn[l]=sum[l];
     63             if(r)
     64                 maxl[r]=maxr[r]=maxn[r]=sum[r];
     65         }
     66         else{
     67             if(l){
     68                 maxl[l]=maxr[l]=0;
     69                 maxn[l]=key[l];
     70             }
     71             if(r){
     72                 maxl[r]=maxr[r]=0;
     73                 maxn[r]=key[r];
     74             }
     75         }
     76     }
     77     if(rev[x]){
     78         rev[x]=0;
     79         rev[l]^=1;
     80         rev[r]^=1;
     81         swp(maxl[l],maxr[l]);
     82         swp(maxl[r],maxr[r]);
     83         swp(ch[l][0],ch[l][1]);
     84         swp(ch[r][0],ch[r][1]);
     85     }
     86 }
     87 inline void rotate(int x){
     88     int p(f[x]),g(f[p]),which(get(x));
     89     pushdown(p);
     90     pushdown(x);
     91     ch[p][which]=ch[x][which^1];
     92     f[ch[p][which]]=p;
     93     ch[x][which^1]=p;
     94     f[p]=x;
     95     f[x]=g;
     96     if(g)
     97         ch[g][ch[g][1]==p]=x;
     98     update(p);
     99     update(x);
    100 }
    101 inline void splay(int x,int y){
    102     pushdown(x);
    103     for(int fa=f[x];fa!=y;rotate(x),fa=f[x])
    104         if(f[fa]!=y)
    105             rotate(get(fa)==get(x)?fa:x);
    106     if(!y)
    107         root=x;
    108 }
    109 inline int find(int x){
    110     int now(root);
    111     while(1){
    112         pushdown(now);
    113         if(x<=size[ch[now][0]])
    114             now=ch[now][0];
    115         else{
    116             int tmp(size[ch[now][0]]+1);
    117             if(x<=tmp)
    118                 return now;
    119             x-=tmp;
    120             now=ch[now][1];
    121         }
    122     }
    123 }
    124 inline void build(int l,int r,int fa){
    125     if(l>r)
    126         return ;
    127     if(l==r){
    128         f[l]=fa;
    129         size[l]=1;
    130         sum[l]=key[l];
    131         if(key[l]>=0)
    132             maxl[l]=maxr[l]=maxn[l]=key[l];
    133         else{
    134             maxl[l]=maxr[l]=0;
    135             maxn[l]=key[l];
    136         }
    137         if(fa){
    138             if(l<fa)
    139                 ch[fa][0]=l;
    140             else
    141                 ch[fa][1]=l;
    142         }
    143         return;
    144     }
    145     int mid((l+r)>>1);
    146     build(l,mid-1,mid);
    147     build(mid+1,r,mid);
    148     f[mid]=fa;
    149     update(mid);
    150     if(fa){
    151         if(mid<fa)
    152             ch[fa][0]=mid;
    153         else
    154             ch[fa][1]=mid;
    155     }
    156 }
    157 inline void erase(int x){
    158     if(!x)
    159         return;
    160     erase(ch[x][0]);
    161     erase(ch[x][1]);
    162     clear(x);
    163 }
    164 char op[10];
    165 inline int gg(){
    166     freopen("seq2005.in","r",stdin);
    167     freopen("seq2005.out","w",stdout);
    168     int n(read()),m(read());
    169     key[++sz]=-1000000000;
    170     for(int i=1;i<=n;i++)
    171         key[++sz]=read();
    172     key[++sz]=-1000000000;
    173     build(1,n+2,0);
    174     root=(n+3)>>1;
    175     int all(n+2);
    176     while(m--){//cout<<'*'<<m<<endl;
    177         scanf("%s",op);
    178         if(op[0]=='I'){
    179             int pos(read()+1),tot(read()),old(sz+1);
    180             int x(find(pos)),y(find(pos+1));
    181             splay(x,0);
    182             splay(y,x);
    183             for(int i=1;i<=tot;i++)
    184                 key[++sz]=read();
    185             build(old,sz,0);
    186             int rt((old+sz)>>1);
    187             f[rt]=y;
    188             ch[y][0]=rt;
    189             update(y);
    190             update(x);
    191             all+=tot;
    192             continue;
    193         }
    194         if(op[0]=='D'){
    195             int pos(read()),tot(read());
    196             int x(find(pos)),y(find(pos+tot+1));
    197             splay(x,0);
    198             splay(y,x);
    199             erase(ch[y][0]);
    200             update(y);
    201             update(x);
    202             all-=tot;
    203             continue;
    204         }
    205         if(op[0]=='R'){
    206             int pos(read()),tot(read());
    207             int x(find(pos)),y(find(pos+tot+1));
    208             splay(x,0);
    209             splay(y,x);
    210             int z(ch[y][0]);
    211             if(!lazy[z]){
    212                 rev[z]^=1;
    213                 swp(ch[z][0],ch[z][1]);
    214                 swp(maxl[z],maxr[z]);
    215                 update(y);
    216                 update(x);
    217             }
    218             continue;
    219         }
    220         if(op[0]=='G'){
    221             int pos(read()),tot(read());
    222             int x(find(pos)),y(find(pos+tot+1));
    223             splay(x,0);
    224             splay(y,x);
    225             printf("%d
    ",sum[ch[y][0]]);
    226             continue;
    227         }
    228         if(op[2]=='K'){
    229             int pos(read()),tot(read()),c(read());
    230             int x(find(pos)),y(find(pos+tot+1));
    231             splay(x,0);
    232             splay(y,x);
    233             int z(ch[y][0]);
    234             lazy[z]=1;
    235             key[z]=c;
    236             sum[z]=size[z]*c;
    237             if(c>=0)
    238                 maxl[z]=maxr[z]=maxn[z]=sum[z];
    239             else{
    240                 maxl[z]=maxr[z]=0;
    241                 maxn[z]=c;
    242             }
    243             update(y);
    244             update(x);
    245         }
    246         if(op[2]=='X'){
    247             int x(find(1)),y(find(all));
    248             splay(x,0);
    249             splay(y,x);
    250             printf("%d
    ",maxn[ch[y][0]]);
    251         }
    252     }
    253     return 0;
    254 }
    255 int K(gg());
    256 int main(){;}
    View Code

    然后成功在COGS上A了,然后我去了HZOJ、洛谷什么的。

    MLE喵喵喵???我难道交了个MLE自动机喵喵喵???

    //MLE自动机
    int main(){
        while(1)
            long long *x=new long long[500];
    }
    //请不要作死在自己电脑上以及他人电脑上使用

    最后我发现,COGS上的限制是这样的:

    时间限制:3 s   内存限制:256 MB

    然而其他OJ的限制是这样的:

    时间限制: 1 Sec  内存限制: 64 MB

    数组就莫名GG了= =

    所以我学(xiu)习(gai)了某司机的指针板子,成功的get√到了新板子= =

    264行SpalySplay板子奉上

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 using namespace std;
      7 inline int read(){
      8     int sum(0),f(1);
      9     char ch(getchar());
     10     for(;ch<'0'||ch>'9';ch=getchar())
     11         if(ch=='-')
     12             f=-1;
     13     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     14     return sum*f;
     15 }
     16 const int inf(0x2FFFFFFF);
     17 inline int my_max(int a,int b){
     18     return a>b?a:b;
     19 }
     20 inline void swp(int &a,int &b){
     21     a^=b;
     22     b^=a;
     23     a^=b;
     24 }
     25 class SplayTree{
     26     private:
     27         class Node{
     28             public:
     29                 int k,sz,sm,lm,rm,ms;
     30                 bool set,rev;
     31                 Node *fa,*ch[2];
     32                 Node(const int& key){
     33                     this->k=key;
     34                     this->sm=key;
     35                     this->ms=key;
     36                     this->lm=key>=0?key:0;
     37                     this->rm=key>=0?key:0;
     38                     this->sz=1;
     39                     this->fa=NULL;
     40                     this->ch[0]=NULL;
     41                     this->ch[1]=NULL;
     42                     this->rev=false;
     43                     this->set=false;
     44                 }
     45                 ~Node(){
     46                     if(this->ch[0]!=NULL)
     47                         delete this->ch[0];
     48                     if(this->ch[1]!=NULL)
     49                         delete this->ch[1];
     50                 }
     51                 inline void pushup(){
     52                     if(this!=NULL){
     53                         this->sz=this->ch[0]->size()+this->ch[1]->size()+1;
     54                         this->sm=this->ch[0]->sum()+this->ch[1]->sum()+this->k;
     55                         this->lm=my_max(this->ch[0]->lmax(),this->ch[0]->sum()+this->k+this->ch[1]->lmax());
     56                         this->rm=my_max(this->ch[1]->rmax(),this->ch[1]->sum()+this->k+this->ch[0]->rmax());
     57                         this->ms=my_max(my_max(this->ch[0]->maxsum(),this->ch[1]->maxsum()),this->ch[0]->rmax()+this->k+this->ch[1]->lmax());
     58                     }
     59                 }
     60                 inline void Swap(){
     61                     if(this!=NULL){
     62                         this->rev=!this->rev;
     63                         swp(this->lm,this->rm);
     64                         swap(this->ch[0],this->ch[1]);
     65                     }
     66                 }
     67                 inline void Set(const int &key){
     68                     if(this!=NULL){
     69                         this->set=true;
     70                         this->k=key;
     71                         this->sm=key*this->sz;
     72                         this->lm=my_max(this->sm,0);
     73                         this->rm=my_max(this->sm,0);
     74                         this->ms=my_max(this->sm,this->k);
     75                     }
     76                 }
     77                 inline void pushdown(){
     78                     if(this->set){
     79                         this->set=this->rev=false;
     80                         this->ch[0]->Set(this->k);
     81                         this->ch[1]->Set(this->k);
     82                     }
     83                     if(this->rev){
     84                         this->rev=false;
     85                         this->ch[0]->Swap();
     86                         this->ch[1]->Swap();
     87                     }
     88                 }
     89                 inline int sum(){
     90                     return this?this->sm:0;
     91                 }
     92                 inline int maxsum(){
     93                     return this?this->ms:-inf;
     94                 }
     95                 inline int key(){
     96                     return this?this->k:0;
     97                 }
     98                 inline int lmax(){
     99                     return this?this->lm:0;
    100                 }
    101                 inline int rmax(){
    102                     return this?this->rm:0;
    103                 }
    104                 inline int size(){
    105                     return this?this->sz:0;
    106                 }
    107         }*root;
    108         inline void rotate(Node *root,int k){
    109             Node *tmp(root->ch[k^1]);
    110             root->pushdown();
    111             tmp->pushdown();
    112             tmp->fa=root->fa;
    113             if(root->fa==NULL)
    114                 this->root=tmp;
    115             else
    116                 if(root->fa->ch[0]==root)
    117                     root->fa->ch[0]=tmp;
    118                 else
    119                     root->fa->ch[1]=tmp;
    120             root->ch[k^1]=tmp->ch[k];
    121             if(tmp->ch[k]!=NULL)
    122                 tmp->ch[k]->fa=root;
    123             tmp->ch[k]=root;
    124             root->fa=tmp;
    125             root->pushup();
    126             tmp->pushup();
    127         }
    128         inline void Splay(Node *root,Node *fa=NULL){
    129             while(root->fa!=fa){
    130                 int k(root->fa->ch[0]==root);
    131                 if(root->fa->fa==fa)
    132                     rotate(root->fa,k);
    133                 else{
    134                     int d(root->fa->fa->ch[0]==root->fa);
    135                     rotate(k==d?root->fa->fa:root->fa,k);
    136                     rotate(root->fa,d);
    137                 }
    138             }
    139         }
    140         inline Node* build(const vector<int> &v,int l,int r){
    141             if(l>r)
    142                 return NULL;
    143             int mid((l+r)>>1);
    144             Node *tmp(new Node(v[mid]));
    145             tmp->ch[0]=build(v,l,mid-1);
    146             tmp->ch[1]=build(v,mid+1,r);
    147             if(tmp->ch[0]!=NULL)
    148                 tmp->ch[0]->fa=tmp;
    149             if(tmp->ch[1]!=NULL)
    150                 tmp->ch[1]->fa=tmp;
    151             tmp->pushup();
    152             return tmp;
    153         }
    154     public:
    155         SplayTree():root(new Node(-inf)){
    156             this->root->ch[1]=new Node(-inf);
    157             this->root->ch[1]->fa=this->root;
    158         }
    159         SplayTree(const vector<int> &v){
    160             this->root=build(v,0,v.size()-1);
    161         }
    162         ~SplayTree(){
    163             delete this->root;
    164         }
    165         Node* Kth(int pos){
    166             ++pos;
    167             Node* root(this->root);//cout<<'+';
    168             while(root!=NULL){
    169                 root->pushdown();
    170                 int k(root->ch[0]->size()+1);
    171                 if(pos<k)
    172                     root=root->ch[0];
    173                 else
    174                     if(pos==k)
    175                         return root;
    176                     else{
    177                         pos-=k;
    178                         root=root->ch[1];
    179                     }
    180             }
    181             return NULL;
    182         }
    183         inline int Sum(const int &pos,const int &len){
    184             this->Splay(this->Kth(pos-1));
    185             this->Splay(this->Kth(pos+len),this->root);
    186             return this->root->ch[1]->ch[0]->sum();
    187         }
    188         inline void Reverse(const int &pos,const int &len){
    189             this->Splay(this->Kth(pos-1));
    190             this->Splay(this->Kth(pos+len),this->root);
    191             this->root->ch[1]->ch[0]->Swap();
    192             this->root->ch[1]->pushup();
    193             this->root->pushup();
    194         }
    195         inline void Set(const int &pos,const int &len,const int &d){
    196             this->Splay(this->Kth(pos-1));
    197             this->Splay(this->Kth(pos+len),this->root);
    198             this->root->ch[1]->ch[0]->Set(d);
    199             this->root->ch[1]->pushup();
    200             this->root->pushup();
    201         }
    202         inline void Insert(const int &pos,SplayTree *data){
    203             this->Splay(this->Kth(pos));
    204             this->Splay(this->Kth(pos+1),this->root);
    205             Node *tmp(data->root);
    206             data->root=NULL;
    207             this->root->ch[1]->ch[0]=tmp;
    208             tmp->fa=this->root->ch[1];
    209             this->root->ch[1]->pushup();
    210             this->root->pushup();
    211         }
    212         inline void Delete(const int &pos,const int &len){
    213             this->Splay(this->Kth(pos-1));
    214             this->Splay(this->Kth(pos+len),this->root);
    215             delete this->root->ch[1]->ch[0];
    216             this->root->ch[1]->ch[0]=NULL;
    217             this->root->ch[1]->pushup();
    218             this->root->pushup();
    219         }
    220         inline int maxsum(){
    221             return this->root->maxsum();
    222         }
    223 };
    224 SplayTree *tree(new SplayTree());
    225 vector<int>v;
    226 char op[20];
    227 int x,y;
    228 inline int gg(){
    229     freopen("seq2005.in","r",stdin);
    230     freopen("seq2005.out","w",stdout);
    231     int n(read()),m(read());
    232     for(int i=0;i<n;i++)
    233         v.push_back(read());
    234     tree->Insert(0,new SplayTree(v));//cout<<'*';
    235     while(m--){
    236         scanf("%s",op);
    237         if(op[0]!='M'||op[2]!='X')
    238             x=read(),y=read();
    239         if(op[0]=='G')
    240             printf("%d
    ",tree->Sum(x,y));
    241         else
    242             if(op[0]=='D')
    243                 tree->Delete(x,y);
    244             else
    245                 if(op[0]=='R')
    246                     tree->Reverse(x,y);
    247                 else
    248                     if(op[0]=='I'){
    249                         v.clear();
    250                         while(y--)
    251                             v.push_back(read());
    252                         tree->Insert(x,new SplayTree(v));
    253                     }
    254                     else
    255                         if(op[0]=='M'){
    256                             if(op[2]=='K')
    257                                 tree->Set(x,y,read());
    258                             else
    259                                 printf("%d
    ",tree->maxsum());
    260                         }
    261     }
    262 }
    263 int K(gg());
    264 int main(){;}
    View Code

    这题,真的虐心啊= =

  • 相关阅读:
    南京的第一场雪 沧海
    再一则笑话家里闹鬼了 沧海
    简单需求描述(自己备用) 沧海
    为什么IIS无法启动,以前是可以了.而且WWW服务也启动不了提示:错误127,找不到指定程序. 沧海
    生活中有着太多的感动 沧海
    Enhancements 沧海
    ABAP SysteTransactions, Tables and Programs 沧海
    SAP ABAP OK Code Values 沧海
    Conversion of SAPSCRIPT to SMARTFORMS 沧海
    别人的面试记实转摘 沧海
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7289215.html
Copyright © 2011-2022 走看看