bzoj4009: [HNOI2015]接水果

http://www.cnblogs.com/New-Godess/p/4450078.html

具体看这个吧

 

然后写完竟然因为节点回收数组太小结果呵呵了一个多小时

 

type
  arr1=record
    next,toward:longint;
  end;
  arr=array[0..5]of longint;
const
  maxm=600000;
  maxn=8000000;

var
  edge:array[0..maxm]of arr1;
  que:array[0..maxm]of arr;
  lson,rson,size,pp:array[0..maxn]of longint;
  root,p1,p,num1,num2,first,fa,deep,ans:array[0..maxm]of longint;
  f1:array[0..60000,0..17]of longint;
  n,m,ptot,pptot,time,esum,trsum,tot,q,mm:longint;

procedure addedge(j,k:longint);
begin
  inc(esum);
  edge[esum].next:=first[j];
  first[j]:=esum;
  edge[esum].toward:=k;
end;

procedure swap(var x,y:longint);
var
  i:longint;
begin
  i:=x;
  x:=y;
  y:=i;
end;

procedure dfs(x:longint);
var
  i,too:longint;
begin
  inc(time);
  num1[x]:=time;
  p[time]:=x;
  i:=first[x];
  while i>0 do begin
    too:=edge[i].toward;
    if fa[x]<>too then begin
      deep[too]:=deep[x]+1;
      fa[too]:=x;
      dfs(too);
    end;
    i:=edge[i].next;
  end;
  num2[x]:=time;
end;

procedure before;
var
  i,j:longint;
begin
  for i:=1 to n do f1[i,0]:=fa[i];
  trsum:=trunc(ln(n)/ln(2));
  for i:=1 to trsum do
    for j:=1 to n do
      f1[j,i]:=f1[f1[j,i-1],i-1];
end;

function lca(x,y:longint):longint;
var
  i:longint;
begin
  for i:=trsum downto 0 do
    if deep[f1[y,i]]>=deep[x] then
      y:=f1[y,i];
  if x=y then exit(x);
  for i:=trsum downto 0 do
    if f1[x,i]<>f1[y,i] then begin
      x:=f1[x,i];
      y:=f1[y,i];
    end;
  exit(f1[x,0]);
end;

procedure add(x,l,r,y,z:longint);
begin
  inc(tot);
  que[tot,0]:=0;
  que[tot,1]:=x;
  que[tot,2]:=l;
  que[tot,3]:=r;
  que[tot,4]:=y;
  que[tot,5]:=z;
end;

procedure qsort(l,r:longint);
var
  i,j,mid1,mid2:longint;
  tmp:arr;
begin
  i:=l;
  j:=r;
  mid1:=que[(l+r)>>1,1];
  mid2:=que[(l+r)>>1,0];
  repeat
    while (que[i,1]<mid1) or (que[i,1]=mid1) and (que[i,0]<mid2) do inc(i);
    while (que[j,1]>mid1) or (que[j,1]=mid1) and (que[j,0]>mid2) do dec(j);
    if i<=j then begin
      tmp:=que[i];
      que[i]:=que[j];
      que[j]:=tmp;
      inc(i);
      dec(j);
    end;
  until i>j;
  if i<r then qsort(i,r);
  if l<j then qsort(l,j);
end;

procedure into;
var
  i,j,k,l,fa1,fa2,ii:longint;
begin
  readln(n,m,q);
  mm:=0;
  esum:=0;
  for i:=1 to n-1 do begin
    readln(j,k);
    addedge(j,k);
    addedge(k,j);
  end;
  deep[1]:=1;
  time:=0;
  fa[1]:=0;
  dfs(1);
  before;
  tot:=0;
  for i:=1 to m do begin
    readln(j,k,l);
    if l>mm then mm:=l;
    if deep[j]>deep[k] then swap(j,k);
    fa1:=lca(j,k);
    if j=fa1 then begin
      fa2:=k;
      for ii:=trsum downto 0 do
        if deep[f1[fa2,ii]]>deep[j] then
          fa2:=f1[fa2,ii];
      add(1,num1[k],num2[k],l,1);
      add(num1[fa2],num1[k],num2[k],l,-1);
      if num2[fa2]<n then begin
        add(num1[k],num2[fa2]+1,n,l,1);
        add(num2[k]+1,num2[fa2]+1,n,l,-1);
      end;
    end
    else begin
      if num1[j]>num1[k] then swap(j,k);
      add(num1[j],num1[k],num2[k],l,1);
      add(num2[j]+1,num1[k],num2[k],l,-1);
    end;
  end;
  for i:=1 to q do begin
    readln(j,k,l);
    if num1[j]>num1[k] then swap(j,k);
    inc(tot);
    que[tot,0]:=1;
    que[tot,1]:=num1[j];
    que[tot,2]:=num1[k];
    que[tot,3]:=l;
    que[tot,4]:=i;
  end;
 { for i:=1 to tot do
    writeln(i:4,que[i,0]:4,que[i,1]:4,que[i,2]:4,que[i,3]:4,que[i,4]:4,que[i,5]:4); }
  qsort(1,tot);
{  writeln;
  for i:=1 to tot do
    writeln(i:4,que[i,0]:4,que[i,1]:4,que[i,2]:4,que[i,3]:4,que[i,4]:4,que[i,5]:4);  }
  que[tot+1,1]:=n+1;
end;

function addpoint:longint;
begin
  if pptot>0 then begin
    lson[pp[pptot]]:=0;
    rson[pp[pptot]]:=0;
    size[pp[pptot]]:=0;
    dec(pptot);
    exit(pp[pptot+1]);
  end;
  inc(ptot);
  exit(ptot);
end;

procedure delete(x:longint);
begin
  if x=0 then exit;
  inc(pptot);
  pp[pptot]:=x;
  delete(lson[x]);
  delete(rson[x]);
end;

procedure schange(var x:longint;l,r,y,z:longint);
var
  mid:longint;
begin
  if x=0 then x:=addpoint;
  inc(size[x],z);
  if size[x]=0 then begin
    delete(x);
    x:=0;
    exit;
  end;
  if l=r then exit;
  mid:=(l+r)>>1;
  if y>mid then schange(rson[x],mid+1,r,y,z)
    else schange(lson[x],l,mid,y,z);
end;

procedure bchange(x,l,r,cl,cr,y,z:longint);
var
  mid:longint;
begin
  if (l=cl) and (r=cr) then begin
    schange(root[x],0,mm,y,z);
    exit;
  end;
  mid:=(l+r)>>1;
  if cl>mid then bchange(x<<1+1,mid+1,r,cl,cr,y,z)
  else
    if cr<=mid then bchange(x<<1,l,mid,cl,cr,y,z)
    else begin
      bchange(x<<1,l,mid,cl,mid,y,z);
      bchange(x<<1+1,mid+1,r,mid+1,cr,y,z);
    end;
end;

function query(x,y:longint):longint;
var
  ll,rr,tot1,now,mid,i:longint;
begin
  ll:=1;
  rr:=n;
  tot1:=0;
  now:=1;
  while true do begin
    if root[now]<>0 then begin
      inc(tot1);
      p1[tot1]:=root[now];
    end;
    if ll=rr then break;
    mid:=(ll+rr)>>1;
    if x<=mid then begin
      rr:=mid;
      now:=now<<1;
    end
    else begin
      ll:=mid+1;
      now:=now<<1+1;
    end;
  end;
  ll:=0;
  rr:=mm;
  while ll<rr do begin
    now:=0;
    for i:=1 to tot1 do
      now:=now+size[lson[p1[i]]];
    mid:=(ll+rr)>>1;
    if y<=now then begin
      for i:=1 to tot1 do
        p1[i]:=lson[p1[i]];
      rr:=mid;
    end
    else begin
      for i:=1 to tot1 do
        p1[i]:=rson[p1[i]];
      ll:=mid+1;
      y:=y-now;
    end;
  end;
  exit(ll);
end;

procedure work;
var
  now,i:longint;
begin
  now:=1;
  for i:=1 to n do begin
    while (que[now,1]=i) and (que[now,0]=0) do begin
      bchange(1,1,n,que[now,2],que[now,3],que[now,4],que[now,5]);
      inc(now);
    end;
    while (que[now,1]=i) and (que[now,0]=1) do begin
      ans[que[now,4]]:=query(que[now,2],que[now,3]);
      inc(now);
    end;
    if now>tot then break;
  end;
  for i:=1 to q do
    writeln(ans[i]);
  readln;
  readln;
end;

begin
  into;
  work;
end.
View Code

 

posted @ 2015-04-28 21:47  Macaulish  阅读(500)  评论(0编辑  收藏  举报