zoukankan      html  css  js  c++  java
  • bzoj4009

    这是一道神题,首先我们不难先到整体二分吧

    下面的问题就是,求出对于每个水果,有多少盘子是他的子路径

    直接考虑不是很容易,我们换个思路,考虑对于每个盘子,哪些水果能包含它

    我们假设盘子a,b,dep[a]<dep[b]

    如果b在a的子树内,不难发现,水果路径必须是一个点在b的子树内(包括b),一个在c的子树外(不包括c,c是ab路径上a下一个点)

    否则 ,水果路径必须两个点分别在a,b子树内

    子树问题不难想到dfs序,设子树x区间为l[x],r[x],盘子路径x,y(l[x]<l[y])满足条件为

    则要满足x∈[1,l[c]-1],y∈[l[b],r[b]或x∈[l[b],r[b]], y∈[l[c]+1,n] 当b在a的子树内

    否则x∈[l[a],r[a]],y∈[l[b],r[b],把(x,y)看做一个点

    也就是现在询问每个点被多少矩形覆盖(注意第一种情形两个矩形是不相交的,所以覆盖的矩形数目就是盘子数目

    矩形覆盖的经典做法是把矩形(x0,y0),(x1,y1)看成4个带权值的点

    (x0,y0) 1, (x0,y1+1) -1, (x1+1,y0) -1 (x1+1,y1+1) 1,

    这样每个询问点最下方(包括边界)的点权值和就是覆盖询问点的矩形数目(画图可知)

    而这个问题我们对一维排序,一维树状数组即可快速解决

      1 type node=record
      2        po,next:longint;
      3      end;
      4      point=record
      5        x,y,id,z:longint;
      6      end;
      7 
      8 var e:array[0..80010] of node;
      9     dep,ans,st,a,b,c,p,d:array[0..50010] of longint;
     10     anc:array[0..40010,0..18] of longint;
     11     q,w,tw:array[0..400010] of point;
     12     can,v:array[0..80010] of boolean;
     13     j,tot,t,x,y,z,i,len,n,m,k,xx:longint;
     14 
     15 function lowbit(x:longint):longint;
     16   begin
     17     exit(x and (-x));
     18   end;
     19 
     20 procedure swap(var a,b:longint);
     21   var c:longint;
     22   begin
     23     c:=a;
     24     a:=b;
     25     b:=c;
     26   end;
     27 
     28 procedure add(x,y:longint);
     29   begin
     30     inc(len);
     31     e[len].po:=y;
     32     e[len].next:=p[x];
     33     p[x]:=len;
     34   end;
     35 
     36 procedure dfs(x:longint);
     37   var i,y:longint;
     38   begin
     39     inc(t);
     40     a[x]:=t;
     41     i:=p[x];
     42     while i<>0 do
     43     begin
     44       y:=e[i].po;
     45       if a[y]=0 then
     46       begin
     47         anc[y,0]:=x;
     48         dep[y]:=dep[x]+1;
     49         dfs(y);
     50       end;
     51       i:=e[i].next;
     52     end;
     53     b[x]:=t;
     54   end;
     55 
     56 function jump(x,d:longint):longint;
     57   var i:longint;
     58   begin
     59     for i:=16 downto 0 do
     60       if dep[x]-1 shl i>=d then x:=anc[x,i];
     61     exit(x);
     62   end;
     63 
     64 function cmp(a,b:point):boolean;
     65   begin
     66     exit((a.x<b.x) or (a.x=b.x) and (a.y<b.y));
     67   end;
     68 
     69 procedure sortc(l,r:longint);
     70   var i,j,x:longint;
     71   begin
     72     i:=l;
     73     j:=r;
     74     x:=c[(l+r) shr 1];
     75     repeat
     76       while c[i]<x do inc(i);
     77       while x<c[j] do dec(j);
     78       if not(i>j) then
     79       begin
     80         swap(c[i],c[j]);
     81         inc(i);
     82         dec(j);
     83       end;
     84     until i>j;
     85     if l<j then sortc(l,j);
     86     if i<r then sortc(i,r);
     87   end;
     88 
     89 procedure sortw(l,r:longint);
     90   var i,j:longint;
     91       x,y:point;
     92   begin
     93     i:=l;
     94     j:=r;
     95     x:=w[(l+r) shr 1];
     96     repeat
     97       while cmp(w[i],x) do inc(i);
     98       while cmp(x,w[j]) do dec(j);
     99       if not(i>j) then
    100       begin
    101         y:=w[i]; w[i]:=w[j]; w[j]:=y;
    102         inc(i);
    103         dec(j);
    104       end;
    105     until i>j;
    106     if l<j then sortw(l,j);
    107     if i<r then sortw(i,r);
    108   end;
    109 
    110 procedure sortq(l,r:longint);
    111   var i,j:longint;
    112       x,y:point;
    113   begin
    114     i:=l;
    115     j:=r;
    116     x:=q[(l+r) shr 1];
    117     repeat
    118       while cmp(q[i],x) do inc(i);
    119       while cmp(x,q[j]) do dec(j);
    120       if not(i>j) then
    121       begin
    122         y:=q[i]; q[i]:=q[j]; q[j]:=y;
    123         inc(i);
    124         dec(j);
    125       end;
    126     until i>j;
    127     if l<j then sortq(l,j);
    128     if i<r then sortq(i,r);
    129   end;
    130 
    131 procedure open(x0,x1,y0,y1,z:longint);
    132   begin
    133     inc(x1); inc(y1);
    134     inc(t); w[t].x:=x0; w[t].y:=y0; w[t].id:=1; w[t].z:=z;
    135     inc(t); w[t].x:=x0; w[t].y:=y1; w[t].id:=-1; w[t].z:=z;
    136     inc(t); w[t].x:=x1; w[t].y:=y0; w[t].id:=-1; w[t].z:=z;
    137     inc(t); w[t].x:=x1; w[t].y:=y1; w[t].id:=1; w[t].z:=z;
    138   end;
    139 
    140 procedure work(x,w:longint);
    141   begin
    142     while x<=n+1 do
    143     begin
    144       if not v[x] then
    145       begin
    146         v[x]:=true;
    147         inc(tot);
    148         st[tot]:=x;
    149       end;
    150       d[x]:=d[x]+w;
    151       x:=x+lowbit(x);
    152     end;
    153   end;
    154 
    155 function ask(x:longint):longint;
    156   begin
    157     ask:=0;
    158     while x>0 do
    159     begin
    160       ask:=ask+d[x];
    161       x:=x-lowbit(x);
    162     end;
    163   end;
    164 
    165 procedure cdq(opx,opy,qx,qy,l,r:longint);
    166   var m,t,i,j,s,f1,f2,z,q1,q2:longint;
    167   begin
    168     if (l>r) or (qx>qy) then exit;
    169     if l=r then
    170     begin
    171       for i:=qx to qy do
    172         ans[q[i].id]:=c[l];
    173       exit;
    174     end;
    175     m:=(l+r) shr 1;  //二分答案
    176     t:=0;
    177     for i:=opx to opy do
    178       if w[i].z<=c[m] then
    179       begin
    180         inc(t);
    181         tw[t]:=w[i];
    182       end;
    183 
    184     z:=0;
    185     j:=1;
    186     for i:=qx to qy do
    187     begin
    188       can[i]:=false;
    189       while (j<=t) and (tw[j].x<=q[i].x) do  //扫描询问
    190       begin
    191         work(tw[j].y,tw[j].id);
    192         inc(j);
    193       end;
    194       s:=ask(q[i].y);
    195       if s>=q[i].z then
    196       begin
    197         ans[q[i].id]:=c[m];
    198         inc(z);
    199         can[i]:=true;
    200       end
    201       else q[i].z:=q[i].z-s;
    202     end;
    203     f1:=opx-1; f2:=opx+t-1;  //划分操作区间
    204     for i:=opx to opy do
    205       if w[i].z<=c[m] then
    206       begin
    207         inc(f1);
    208         tw[f1]:=w[i];
    209       end
    210       else begin
    211         inc(f2);
    212         tw[f2]:=w[i];
    213       end;
    214     for i:=opx to opy do
    215       w[i]:=tw[i];
    216     q1:=qx-1; q2:=qx+z-1;
    217     for i:=qx to qy do
    218       if can[i] then
    219       begin
    220         inc(q1);
    221         tw[q1]:=q[i];
    222       end
    223       else begin
    224         inc(q2);
    225         tw[q2]:=q[i];
    226       end;
    227     for i:=qx to qy do
    228       q[i]:=tw[i];
    229     for i:=1 to tot do
    230     begin
    231       s:=st[i];
    232       v[s]:=false;
    233       d[s]:=0;
    234     end;
    235     tot:=0;
    236     cdq(opx,f1,qx,q1,l,m);
    237     cdq(f1+1,opy,q1+1,qy,m+1,r);
    238   end;
    239 
    240 begin
    241   readln(n,m,k);
    242   for i:=1 to n-1 do
    243   begin
    244     readln(x,y);
    245     add(x,y);
    246     add(y,x);
    247   end;
    248   dfs(1);
    249   for j:=1 to trunc(ln(n)/ln(2))+1 do
    250     for i:=1 to n do
    251     begin
    252       x:=anc[i,j-1];
    253       anc[i,j]:=anc[x,j-1];
    254     end;
    255 
    256   t:=0;
    257   for i:=1 to m do
    258   begin
    259     readln(x,y,z);
    260     if a[x]>a[y] then swap(x,y);
    261     if a[y]<=b[x] then
    262     begin
    263       xx:=jump(y,dep[x]+1);
    264       if a[xx]<>1 then open(1,a[xx]-1,a[y],b[y],z);
    265       if b[xx]<n then open(a[y],b[y],b[xx]+1,n,z);
    266     end
    267     else open(a[x],b[x],a[y],b[y],z);
    268     c[i]:=z;
    269   end;
    270   sortc(1,m);
    271   sortw(1,t);
    272   for i:=1 to k do
    273   begin
    274     readln(x,y,z);
    275     if a[x]>a[y] then swap(x,y);
    276     q[i].x:=a[x]; q[i].y:=a[y]; q[i].id:=i; q[i].z:=z;
    277   end;
    278   sortq(1,k);
    279   cdq(1,t,1,k,1,m);
    280   for i:=1 to k do
    281     writeln(ans[i]);
    282 end.
    View Code
  • 相关阅读:
    【模板】2-SAT 问题
    HDU5875 Function
    Codeforces Round #380 (Div. 2)/729B Spotlights 水题
    Codeforces Round #380 (Div. 2)/729E Subordinates 贪心
    Codeforces Round #380 (Div. 2)/729D Sea Battle 思维题
    HDU 5869 Different GCD Subarray Query 树状数组+离线
    HDU 5696 区间的价值 暴力DFS
    HDU 5876 Sparse Graph BFS+set删点
    HDU 5868 Different Circle Permutation Burnside引理+矩阵快速幂+逆元
    HDU 5800 To My Girlfriend DP
  • 原文地址:https://www.cnblogs.com/phile/p/4490782.html
Copyright © 2011-2022 走看看