哎呀,不早了,这道题从9点调到了11:30,总之这道题和之前的【poj3580】非常相似,很欣慰的是这次编写的时候思维非常连贯,一口气写完,debug了2个小时发现一直是读入萎了~~,不知道我的数据是不是noi官网的,总之有些点和题目描述的不一样,比如说GET-MAX操作后面诡异的给我来了几个空格,我就一直在201和215之间徘徊。
依然是裸的splay,发现这次的时间有一些惊险,某个点我要8S才跑得出来,主要是回收废节点编号慢了,去掉就大约是3S左右,(ms时限有10S),开了release以后神速!每个点都不超过2S,很奇怪啊。
这道题貌似是没有内存限制的,但是为了不把自己机器卡爆,加了一个回收站把不要的节点编号回收回来下次继续使用。
代码仅供自己观摩。。。。(WS缩行流)
program ex2; const maxn=500005; var max,w,s,sum,lm,rm,c,l,r,next:array[0..maxn] of longint; fan:array[0..maxn] of boolean; i,j,k,n,m,pos,tot,tmp,root,head,ask:longint; task:string;p:char; procedure getmax(var a:longint;b:longint);begin if a<b then a:=b end; procedure update(i:longint);var ll,rr:longint; begin ll:=l[i];rr:=r[i]; s[i]:=s[ll]+s[rr]+1; sum[i]:=sum[ll]+sum[rr]+w[i]; lm[i]:=lm[ll];rm[i]:=rm[rr]; getmax(lm[i],lm[rr]+sum[ll]+w[i]); getmax(rm[i],rm[ll]+sum[rr]+w[i]); max[i]:=lm[rr]+rm[ll]+w[i]; getmax(max[i],max[ll]); getmax(max[i],max[rr]); end; procedure left(var i:longint);var j:longint; begin j:=r[i];r[i]:=l[j];l[j]:=i; update(i);update(j);i:=j; end; procedure right(var i:longint);var j:longint; begin j:=l[i];l[i]:=r[j];r[j]:=i; update(i);update(j);i:=j; end; procedure put(i,cc:longint;ff:boolean); begin if i=0 then exit; if ff then begin tmp:=l[i];l[i]:=r[i];r[i]:=tmp; tmp:=lm[i];lm[i]:=rm[i];rm[i]:=tmp; fan[i]:=not fan[i]; end; if cc<1001 then begin c[i]:=cc;w[i]:=cc;sum[i]:=s[i]*cc; max[i]:=0;getmax(max[i],sum[i]); lm[i]:=max[i];rm[i]:=max[i]; if max[i]=0 then max[i]:=cc; end; end; procedure splay(var i:longint;k:longint); begin put(l[i],c[i],fan[i]);put(r[i],c[i],fan[i]); fan[i]:=false;c[i]:=10000;tmp:=s[l[i]]+1; if k=tmp then exit else if k>tmp then begin splay(r[i],k-tmp);left(i); end else begin splay(l[i],k);right(i); end; end; procedure buildtree(ll,rr:longint;var i:longint); begin if ll>rr then exit; i:=(ll+rr)div 2; buildtree(ll,i-1,l[i]); buildtree(i+1,rr,r[i]); update(i); end; procedure release(i:longint); begin if i=0 then exit; next[i]:=head;head:=i; release(l[i]);release(r[i]); end; begin assign(input,'sequence.in');reset(input); assign(output,'sequence.out');rewrite(output); readln(n,m); fillchar(c,sizeof(c),1); w[1]:=-10000;w[n+2]:=-10000;max[0]:=-10000; for i:=2 to n+1 do read(w[i]);readln; for i:=n+3 to maxn do begin next[i]:=head;head:=i; end; buildtree(1,n+2,root); for m:=1 to m do begin task:='';read(p); while not (p in ['A'..'Z','-']) do read(p); while p in ['A'..'Z','-'] do begin task:=task+p;read(p); end; if task='INSERT' then begin read(pos,tot);splay(root,pos+2); for tot:=1 to tot do begin read(j); k:=head;head:=next[head]; w[k]:=j;l[k]:=l[root];l[root]:=k; r[k]:=0;c[k]:=10000;fan[k]:=false; update(k);update(root); end; end else if task='DELETE' then begin read(pos,tot); splay(root,pos);splay(root,pos+tot+1); release(r[l[root]]);r[l[root]]:=0; update(l[root]);update(root); end else if task='MAKE-SAME' then begin read(pos,tot,j); splay(root,pos);splay(root,pos+tot+1); put(r[l[root]],j,false); update(l[root]);update(root); end else if task='REVERSE' then begin read(pos,tot); splay(root,pos);splay(root,pos+tot+1); put(r[l[root]],10000,true); update(l[root]);update(root); end else if task='GET-SUM' then begin read(pos,tot); splay(root,pos);splay(root,pos+tot+1); writeln(sum[r[l[root]]]); end else writeln(max[root]); end; close(input);close(output); end.