zoukankan      html  css  js  c++  java
  • COJ WZJ的数据结构(负十八)splay_tree的天堂

    WZJ的数据结构(负十八)
    难度级别:E; 运行时间限制:100000ms; 运行空间限制:700KB; 代码长度限制:2000000B
    试题描述

    对于前一段样例:

    输入
    输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。 
    第2行包含N个数字,描述初始时的数列。 
    以下M行,每行一条命令,格式参见问题描述中的表格。为了考察垃圾回收的使用,我们精心准备了多组数据。。。
    输出
    对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。 
    输入示例
    9 8
    2 -6 3 5 1 -5 -3 6 3
    GET-SUM 5 0
    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
    3 3
    1 2 3
    MAKE-SAME 1 3 3
    MAX-SUM
    MAX-SUM
    输出示例
    -1
    10
    1
    10
    9
    9
    其他说明
    样例见题目图片。
    你可以认为在任何时刻,数列中至少有1个数。 
    输入数据一定是正确的,即指定位置的数在数列中一定存在。  
    50%的数据中,任何时刻数列中最多含有100个数; 100%的数据中,任何时刻数列中最多含有500个数。  
    100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。 
    100%的数据中,M ≤20 000,插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
    注意内存限制。请块状链表选手自重;由于数据不太好请Splay选手谨慎使用双旋。

    更新:常数很小的一个版本,而且似乎要少coding一点。但是很容易写错?(雾

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 #define CH for(int d=0;d<=1;d++) if(ch[d])
     10 using namespace std;
     11 const int maxn=500+10,inf=-1u>>1;inline int read();
     12 int max(int a,int b,int c){return max(max(a,b),c);}
     13 struct node{
     14     node*fa,*ch[2];
     15     int x,sm,mx,lx,rx,siz,set;bool rev;
     16     void init(){fa=ch[0]=ch[1]=NULL;x=sm=mx=lx=0;siz=1;set=inf;rev=false;return;}
     17     void revt(){
     18         swap(ch[0],ch[1]);swap(lx,rx);rev^=1;return;
     19     }
     20     void sett(int tag){
     21         set=x=tag;sm=tag*siz;mx=lx=rx=max(tag,tag*siz);return;
     22     }
     23     void down(){
     24         if(rev){CH{ch[d]->revt();}rev=false;}
     25         if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
     26         return;
     27     }
     28     void update(){
     29         if(ch[0]&&ch[1]){
     30             siz=1+ch[0]->siz+ch[1]->siz;
     31             sm=x+ch[0]->sm+ch[1]->sm;
     32             lx=max(ch[0]->lx,ch[0]->sm+x+max(0,ch[1]->lx));
     33             rx=max(ch[1]->rx,ch[1]->sm+x+max(0,ch[0]->rx));
     34             mx=max(ch[0]->mx,ch[1]->mx,max(0,ch[0]->rx)+x+max(0,ch[1]->lx));
     35         }
     36         else if(ch[0]){
     37             siz=1+ch[0]->siz;
     38             sm=x+ch[0]->sm;
     39             lx=max(ch[0]->lx,ch[0]->sm+x);
     40             rx=x+max(0,ch[0]->rx);
     41             mx=max(ch[0]->mx,max(0,ch[0]->rx)+x);
     42         }
     43         else if(ch[1]){
     44             siz=1+ch[1]->siz;
     45             sm=x+ch[1]->sm;
     46             lx=x+max(0,ch[1]->lx);
     47             rx=max(ch[1]->rx,ch[1]->sm+x);
     48             mx=max(ch[1]->mx,x+max(0,ch[1]->lx));
     49         }
     50         else{
     51             siz=1;sm=x;lx=rx=mx=x;
     52         } return;
     53     }
     54 }Splay[maxn],*root,*nodecnt;
     55 queue<node*>RAM;
     56 void nodeinit(){
     57     nodecnt=Splay;return;
     58 }
     59 node*newnode(){
     60     node*t;if(!RAM.empty()) t=RAM.front(),RAM.pop();
     61     else t=nodecnt++;t->init();return t;
     62 }
     63 void del(node*&x){RAM.push(x);return;}
     64 void deltree(node*&x){if(!x)return;deltree(x->ch[0]);deltree(x->ch[1]);del(x);return;}
     65 int parent(node*x,node*&y){return (y=x->fa)?y->ch[0]==x?0:y->ch[1]==x?1:-1:-1;}
     66 void rotate(node*x){
     67     node*y,*z;int d1=parent(x,y),d2=parent(y,z);
     68     if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
     69     y->fa=x;x->fa=z;x->ch[d1^1]=y;
     70     if(d2!=-1) z->ch[d2]=x;
     71     y->update();return;
     72 }
     73 void pushdown(node*x){
     74     static node*s[maxn];int top=0;
     75     for(node*y;;x=y){
     76         s[top++]=x;y=x->fa;
     77         if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break;
     78     } while(top--) s[top]->down();return;
     79 }
     80 node*splay(node*x){
     81     pushdown(x);node*y,*z;int d1,d2;
     82     while(true){
     83         if((d1=parent(x,y))<0) break;
     84         if((d2=parent(y,z))<0){rotate(x);break;}
     85         if(d1==d2) rotate(y),rotate(x);
     86         else rotate(x),rotate(x);
     87     } x->update();return x;
     88 }
     89 node*find(node*x,int rank){
     90     x->down();int kth=x->ch[0]?x->ch[0]->siz+1:1;
     91     if(rank==kth) return x;
     92     if(rank<kth) return find(x->ch[0],rank);
     93     else return find(x->ch[1],rank-kth);
     94 }
     95 node*findlast(node*x){
     96     while(x->ch[1]) x->down(),x=x->ch[1];return x;
     97 }
     98 void split(node*&x,node*&y,int a){
     99     if(!a){y=x;x=NULL;return;}
    100     x=splay(find(x,a));y=x->ch[1];x->ch[1]=NULL;
    101     if(y)y->fa=NULL;x->update();return;
    102 }
    103 void split(node*&x,node*&y,node*&z,int a,int b){
    104     split(x,z,b);split(x,y,a-1);return;
    105 }
    106 void join(node*&x,node*y){
    107     if(!x){x=y;return;}if(!y)return;
    108     x=splay(findlast(x));x->ch[1]=y;
    109     if(y)y->fa=x;x->update();return;
    110 }
    111 void join(node*&x,node*y,node*z){
    112     join(y,z);join(x,y);return;
    113 }
    114 int A[maxn];
    115 void build(node*&x,int L,int R){
    116     if(L>R)return;int M=L+R>>1;x=newnode();x->x=A[M];
    117     build(x->ch[0],L,M-1);build(x->ch[1],M+1,R);
    118     if(x->ch[0]) x->ch[0]->fa=x;
    119     if(x->ch[1]) x->ch[1]->fa=x;
    120     x->update();return;
    121 }
    122 void insert(int pos,int num){
    123     for(int i=0;i<num;i++) A[i]=read();
    124     node*x,*y;build(x,0,num-1);
    125     split(root,y,pos);join(root,x,y);return;
    126 }
    127 void remove(int pos,int num){
    128     node*x,*y;split(root,x,y,pos,pos+num-1);join(root,y);deltree(x);return;
    129 }
    130 void settag(int pos,int num,int tag){
    131     node*x,*y;split(root,x,y,pos,pos+num-1);x->sett(tag);join(root,x,y);return;
    132 }
    133 void revtag(int pos,int num){
    134     node*x,*y;split(root,x,y,pos,pos+num-1);x->revt();join(root,x,y);return;
    135 }
    136 int maxsum(int pos,int num){
    137     if(!num)return 0;node*x,*y;split(root,x,y,pos,pos+num-1);int ans=x->sm;join(root,x,y);return ans;
    138 }
    139 int maxssm(){return root->mx;}
    140 void printer(node*x){
    141     if(!x) return;x->down();
    142     printer(x->ch[0]);
    143     printf("%d ",x->x);
    144     printer(x->ch[1]);
    145     return;
    146 }
    147 inline int read(){
    148     int x=0,sig=1;char ch=getchar();
    149     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    150     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    151     return x*=sig;
    152 }
    153 inline void write(int x){
    154     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    155     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    156     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    157 }
    158 void init(){
    159     nodeinit();int n,m,pos,num;char s[15];
    160     while(scanf("%d%d",&n,&m)==2){
    161         for(int i=0;i<n;i++) A[i]=read();build(root,0,n-1);
    162         while(m--){
    163             scanf("%s",s);
    164             if(s[0]=='M'&&s[2]=='X'){write(maxssm());ENT;continue;}
    165             pos=read();num=read();
    166             if(s[0]=='I') insert(pos,num);
    167             else if(s[0]=='D') remove(pos,num);
    168             else if(s[0]=='M') settag(pos,num,read());
    169             else if(s[0]=='R') revtag(pos,num);
    170             else write(maxsum(pos,num)),ENT;
    171         } deltree(root);
    172     }
    173     return;
    174 }
    175 void work(){
    176     return;
    177 }
    178 void print(){
    179     return;
    180 }
    181 int main(){init();work();print();return 0;}

    原来copy内存的不要命的做法。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 #define CH for(int d=0;d<=1;d++) if(ch[d])
     10 using namespace std;
     11 const int maxn=500+10,inf=-1u>>1;
     12 int max(int a,int b,int c){return max(a,max(b,c));}
     13 struct node{
     14     node*fa,*ch[2];
     15     int x;bool rev;int siz,sm,set,lx,rx,mx;
     16     node(){ch[0]=ch[1]=NULL;x=sm=0;lx=rx=mx=-inf;set=inf;rev=false;siz=1;}
     17     void init(){ch[0]=ch[1]=NULL;x=sm=0;lx=rx=mx=-inf;set=inf;rev=false;siz=1;return;}
     18     void revt(){swap(ch[0],ch[1]);swap(lx,rx);rev^=1;return;}
     19     void sett(int tag){x=set=tag;sm=tag*siz;lx=rx=mx=max(tag,tag*siz);return;}
     20     void update();
     21     void down(){
     22         if(rev){CH{ch[d]->revt();}rev=false;}
     23         if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
     24         return;
     25     }
     26 }Splay[maxn],*root;int nodecnt=0;
     27 queue<node*>RAM;
     28 node*newnode(){
     29     node*t;if(!RAM.empty()) t=RAM.front(),RAM.pop();
     30     else t=&Splay[nodecnt++];t->init();return t;
     31 }
     32 void del(node*&x){RAM.push(x);return;}
     33 void deltree(node*&x){
     34     if(!x)return;deltree(x->ch[0]);deltree(x->ch[1]);del(x);return;
     35 }
     36 void copy(node*&x,node*y){
     37     x->x=y->x;
     38     x->lx=y->lx;
     39     x->mx=y->mx;
     40     x->rx=y->rx;
     41     x->sm=y->sm;
     42     x->siz=y->siz;
     43     x->set=y->set;
     44     x->rev=y->rev;
     45     return;
     46 }
     47 void node::update(){
     48     siz=1;sm=x;lx=mx=rx=0;node*n[2];n[0]=newnode();n[1]=newnode();
     49     CH{siz+=ch[d]->siz;sm+=ch[d]->sm;copy(n[d],ch[d]);}
     50     lx=max(n[0]->lx,n[0]->sm+x+max(0,n[1]->lx));
     51     rx=max(n[1]->rx,n[1]->sm+x+max(0,n[0]->rx));
     52     mx=max(0,n[0]->rx)+x+max(0,n[1]->lx);
     53     mx=max(n[0]->mx,n[1]->mx,mx);
     54     del(n[0]);del(n[1]);
     55     return;
     56 }
     57 int parent(node*x,node*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;}
     58 void rotate(node*x){
     59     node*y,*z;int d1=parent(x,y),d2=parent(y,z);
     60     if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
     61     y->fa=x;x->fa=z;x->ch[d1^1]=y;
     62     if(d2!=-1) z->ch[d2]=x;
     63     y->update();return;
     64 }
     65 void pushdown(node*x){
     66     static node*s[maxn];int top=0;
     67     for(node*y;;x=y){
     68         s[top++]=x;y=x->fa;
     69         if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break;
     70     } while(top--) s[top]->down();return;
     71 }
     72 node*splay(node*x){
     73     pushdown(x);node*y,*z;int d1,d2;
     74     while(true){
     75         if((d1=parent(x,y))<0) break;
     76         if((d2=parent(y,z))<0){rotate(x);break;}
     77         if(d1==d2) rotate(y),rotate(x);
     78         else rotate(x),rotate(x);
     79     } x->update();return x;
     80 }
     81 node*find(node*x,int rank){
     82     x->down();int kth=1;if(x->ch[0]) kth=x->ch[0]->siz+1;
     83     if(rank==kth) return x;
     84     if(rank<kth) return find(x->ch[0],rank);
     85     else return find(x->ch[1],rank-kth);
     86 }
     87 void split(node*&x,node*&y,int a){
     88     if(!a){y=x;x=NULL;return;}
     89     x=splay(find(x,a));y=x->ch[1];
     90     x->ch[1]=NULL;if(y)y->fa=NULL;x->update();return;
     91 }
     92 void split(node*&x,node*&y,node*&z,int a,int b){
     93     split(x,z,b);split(x,y,a-1);return;
     94 }
     95 void join(node*&x,node*y){
     96     if(!x){x=y;return;}if(!y)return;
     97     x=splay(find(x,x->siz));x->ch[1]=y;
     98     if(y)y->fa=x;x->update();return;
     99 }
    100 void join(node*&x,node*y,node*z){
    101     join(y,z);join(x,y);return;
    102 }
    103 inline int read(){
    104     int x=0,sig=1;char ch=getchar();
    105     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    106     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    107     return x*sig;
    108 }
    109 inline void write(int x){
    110     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    111     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    112     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    113 }
    114 int s[maxn];
    115 void build(node*&x,int L,int R){
    116     if(L>R)return;int M=L+R>>1;
    117     x=newnode();x->x=s[M];
    118     build(x->ch[0],L,M-1);
    119     build(x->ch[1],M+1,R);
    120     if(x->ch[0]) x->ch[0]->fa=x;
    121     if(x->ch[1]) x->ch[1]->fa=x;
    122     x->update();return;
    123 }
    124 void insert(int pos,int num){
    125     int ms=0;for(int i=0;i<num;i++) s[ms++]=read();
    126     node*x,*y;build(x,0,num-1);
    127     split(root,y,pos);join(root,x,y);return;
    128 }
    129 void remove(int L,int R){
    130     node*x,*y;split(root,x,y,L,R);deltree(x);join(root,y);return;
    131 }
    132 void settag(int L,int R,int tag){
    133     node*x,*y;split(root,x,y,L,R);x->sett(tag);join(root,x,y);return;
    134 }
    135 int getsum(int L,int R){
    136     node*x,*y;split(root,x,y,L,R);int sm=x->sm;join(root,x,y);return sm;
    137 }
    138 int getssm(int L,int R){
    139     node*x,*y;split(root,x,y,L,R);int mx=x->mx;join(root,x,y);return mx;
    140 }
    141 void reverse(int L,int R){
    142     node*x,*y;split(root,x,y,L,R);x->revt();join(root,x,y);return;
    143 }
    144 void init(){
    145     int n,Q;int pos,k,v;char str[15];
    146     while(scanf("%d%d",&n,&Q)==2){
    147         for(int i=0;i<n;i++) s[i]=read();build(root,0,n-1);
    148         while(Q--){
    149             scanf("%s",str);
    150             if(str[0]=='I'){
    151                 pos=read();k=read();
    152                 insert(pos,k);
    153             }
    154             else if(str[0]=='D'){
    155                 pos=read();k=read();
    156                 remove(pos,pos+k-1);
    157             }
    158             else if(!strcmp(str,"MAKE-SAME")){
    159                 pos=read();k=read();v=read();
    160                 settag(pos,pos+k-1,v);
    161             }
    162             else if(!strcmp(str,"REVERSE")){
    163                 pos=read();k=read();
    164                 reverse(pos,pos+k-1);
    165             }
    166             else if(!strcmp(str,"GET-SUM")){
    167                 pos=read();k=read();
    168                 if(!k){puts("0");continue;}
    169                 write(getsum(pos,pos+k-1));ENT;
    170             }
    171             else write(getssm(1,root->siz)),ENT;
    172         } deltree(root);
    173     }
    174     return;
    175 }
    176 void work(){
    177     return;
    178 }
    179 void print(){
    180     return;
    181 }
    182 int main(){init();work();print();return 0;}
  • 相关阅读:
    nginx+keepalived实现高可用
    zookeeper集群和安装dubbo的管控台
    常见设计模式的解析和实现(C++)
    sed的工作原理(pattern space 和 hold space)
    sed学习笔记
    C++协助破案问题
    C++中extern “C”含义深层探索
    阿里巴巴笔试第28题
    阿里巴巴集团2014校园招聘笔试题(研发工程师--北邮站)
    淘宝数据魔方技术架构解析
  • 原文地址:https://www.cnblogs.com/chxer/p/4558658.html
Copyright © 2011-2022 走看看