| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
求高人指点错误!Binary search+SBT+单调队列,本机random的极限数据什么事也没有,提交就Runtime error,求高人指点!
program fndslnln;
var
s,f,key,a,v:array[-1000..100000] of int64;
q,left,right,size:array[-1000..100000] of longint;
i,j,k,n,p,l,r,mid,open,closed,root,num,x:longint;
m,temp:int64;
nosol:boolean;
function bsearch(x:longint):longint;
begin
l:=1;r:=x;
while l<r do
begin
mid:=(l+r)>>1;
if s[x]-s[mid-1]<=m then r:=mid else l:=mid+1;
end;
exit(l);
end;
procedure init;
begin
readln(n,m);
for i:=1 to n do
begin
read(a[i]);
s[i]:=s[i-1]+a[i];
if a[i]>m then nosol:=true;
end;
end;
procedure left_rotate(var root:longint);
begin
k:=right[root];
right[root]:=left[k];
left[k]:=root;
size[k]:=size[root];
size[root]:=size[left[root]]+size[right[root]]+1;
root:=k;
end;
procedure right_rotate(var root:longint);
begin
k:=left[root];
left[root]:=right[k];
right[k]:=root;
size[k]:=size[root];
size[root]:=size[left[root]]+size[right[root]]+1;
root:=k;
end;
procedure maintain(var root:longint;bz:boolean);
begin
if bz then
begin
if size[right[right[root]]]>size[left[root]] then left_rotate(root)
else if size[left[right[root]]]>size[left[root]] then
begin
right_rotate(right[root]);
left_rotate(root);
end else exit;
end else
begin
if size[left[left[root]]]>size[right[root]] then right_rotate(root)
else if size[right[left[root]]]>size[right[root]] then
begin
left_rotate(left[root]);
right_rotate(root);
end else exit;
end;
maintain(left[root],false);
maintain(right[root],true);
maintain(root,false);
maintain(root,true);
end;
procedure insert(var root:longint;value:int64);
begin
if root=0 then
begin
inc(num);
root:=num;
left[num]:=0;
right[num]:=0;
key[num]:=value;
size[num]:=1;
end else
begin
inc(size[root]);
if value<key[root] then insert(left[root],value)
else insert(right[root],value);
maintain(root,value>=key[root]);
end;
end;
function delete(var root:longint;value:int64):int64;
begin
dec(size[root]);
if (value=key[root]) or ((value<key[root]) and (left[root]=0)) or ((value>key[root]) and (right[root]=0)) then
begin
delete:=key[root];
if (left[root]=0) or (right[root]=0) then root:=left[root]+right[root]
else key[root]:=delete(left[root],key[root]+1);
end else
if value<key[root] then exit(delete(left[root],value))
else exit(delete(right[root],value));
end;
function find_min(root:longint):int64;
begin
x:=root;
while left[x]<>0 do x:=left[x];
exit(key[x]);
end;
procedure main;
begin
f[1]:=a[1];
q[1]:=1;
open:=0;closed:=1;
for i:=1 to n do
begin
p:=bsearch(i);
while (open<=closed) and (a[q[closed]]<=a[i]) do
begin
if open<>closed then delete(root,f[q[closed-1]]+a[q[closed]]);
dec(closed);
end;
while (open<=closed) and (q[open]+1<p) do
begin
if open<>closed then delete(root,f[q[open]]+a[q[open+1]]);
inc(open);
end;
inc(closed);
q[closed]:=i;
if open<>closed then
begin
v[closed]:=f[q[closed-1]]+a[i];
insert(root,v[closed]);
end;
f[i]:=f[p-1]+a[q[open]];
temp:=find_min(root);
if (temp<f[i]) and (temp>0) then f[i]:=temp;
end;
writeln(f[n]);
end;
begin
// assign(input,'p3017.in');reset(input);
// assign(output,'p3017.out');rewrite(output);
init;
if nosol then writeln(-1) else main;
// close(input);close(output);
end.
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator