哎呀,不早了,这道题从9点调到了11:30,总之这道题和之前的【poj3580】非常相似,很欣慰的是这次编写的时候思维非常连贯,一口气写完,debug了2个小时发现一直是读入萎了~~,不知道我的数据是不是noi官网的,总之有些点和题目描述的不一样,比如说GET-MAX操作后面诡异的给我来了几个空格,我就一直在201和215之间徘徊。
依然是裸的splay,发现这次的时间有一些惊险,某个点我要8S才跑得出来,主要是回收废节点编号慢了,去掉就大约是3S左右,(ms时限有10S),开了release以后神速!每个点都不超过2S,很奇怪啊。
这道题貌似是没有内存限制的,但是为了不把自己机器卡爆,加了一个回收站把不要的节点编号回收回来下次继续使用。
代码仅供自己观摩。。。。(WS缩行流)
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.