Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

求高人指点错误!

Posted by pwecar at 2010-08-27 10:00:12 on Problem 3017
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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator