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选手谨慎使用双旋。 |
题解:注意内存的妥善利用。
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(‘\n‘) 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;}
时间: 2024-12-08 09:22:20