• 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
  • 相关阅读:
    vue事件处理器--v-on
    vue循环-- v-for
    node-Socket编程
    JsonWebToken
    Mongodb 数据库
    Nodejs库-EXPRESS
    yarn和npm的区别
    Vue学习笔记【22】——Vue中的动画(列表的排序过渡)
    Vue学习笔记【21】——Vue中的动画(v-for 的列表过渡)
    Vue学习笔记【20】——Vue中的动画(使用动画钩子函数)
  • 原文地址:https://www.cnblogs.com/Macaulish/p/4464145.html
Copyright © 2020-2023  润新知