# [BZOJ2006][NOI2010]超级钢琴

2A的题，因为又忘开64位了……不应该啊不应该。不过我还是不明白算术上溢为什么是WA而不是RE

1、左端点为x，右端点由y(t-1)

2、左端点为x，右端点由(t+1)z

program bzoj2006;
const maxn=500010;
type heappoint=record x,l,r,m:longint;s:int64; end;
var n,k,ll,rr,i,tmp,size,j:longint;
data:array[0..maxn] of longint;
sum:array[0..maxn] of int64;
st:array[0..maxn,0..20] of longint;
pow:array[0..20] of longint;
log:array[0..2*maxn] of longint;
temp:heappoint;
heap:array[0..2*maxn] of heappoint;
ans:int64;
procedure swap(var x,y:heappoint);
var temp:heappoint;
begin
temp:=x; x:=y; y:=temp;
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
function findmax(l,r:longint):longint;
begin
if sum[st[l,log[r-l+1]]]>sum[st[r-pow[log[r-l+1]]+1,log[r-l+1]]] then
exit(st[l,log[r-l+1]]) else exit(st[r-pow[log[r-l+1]]+1,log[r-l+1]]);
end;
procedure join(x:heappoint);
var i:longint;
begin
inc(size);
heap[size]:=x;
i:=size;
while (i>1)and(heap[i].s>heap[i shr 1].s) do
begin
swap(heap[i],heap[i shr 1]);
i:=i shr 1;
end;
end;
procedure del(x:longint);
var i:longint;
begin
heap[x]:=heap[size];
dec(size);
while x shl 1<=size do
begin
if x shl 1=size then i:=size
else if heap[x shl 1].s>heap[x shl 1+1].s then i:=x shl 1
else i:=x shl 1+1;
if heap[i].s>heap[x].s then
begin
swap(heap[i],heap[x]);
x:=i;
end else exit;
end;
end;
begin
for i:=1 to n do readln(data[i]);
sum[0]:=0;
for i:=1 to n do sum[i]:=sum[i-1]+data[i];
pow[0]:=1;
for i:=1 to 20 do
begin
pow[i]:=pow[i-1] shl 1;
if pow[i]>n then break;
end;
for i:=1 to 20 do
begin
if pow[i]=0 then break;
for j:=pow[i-1] to pow[i]-1 do log[j]:=i-1;
end;
for i:=1 to n do st[i,0]:=i;
for j:=1 to 20 do
begin
if pow[j]>n then break;
for i:=1 to n do
if (i+pow[j-1])>n then st[i,j]:=st[i,j-1]
else if sum[st[i,j-1]]>sum[st[i+pow[j-1],j-1]] then st[i,j]:=st[i,j-1]
else st[i,j]:=st[i+pow[j-1],j-1];
end;
size:=0;
for i:=1 to n-ll+1 do
begin
temp.x:=i;
temp.l:=i+ll-1;
temp.r:=min(i+rr-1,n);
temp.m:=findmax(temp.l,temp.r);
temp.s:=sum[temp.m]-sum[i-1];
join(temp);
end;
ans:=0;
for i:=1 to k do
begin
ans:=ans+heap[1].s;
temp:=heap[1];
tmp:=heap[1].m;
if tmp>temp.l then
begin
temp.r:=tmp-1;
temp.m:=findmax(temp.l,tmp-1);
temp.s:=sum[temp.m]-sum[temp.x-1];
join(temp);
end;
temp:=heap[1];
if tmp<temp.r then
begin
temp.l:=tmp+1;
temp.m:=findmax(temp.l,temp.r);
temp.s:=sum[temp.m]-sum[temp.x-1];
join(temp);
end;
del(1);
end;
writeln(ans);
end.

posted @ 2016-05-02 17:30 lkmcfj 阅读(...) 评论(...) 编辑 收藏