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