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
  • 相关阅读:
    背水一战 Windows 10 (90)
    背水一战 Windows 10 (89)
    背水一战 Windows 10 (88)
    背水一战 Windows 10 (87)
    背水一战 Windows 10 (86)
    背水一战 Windows 10 (85)
    背水一战 Windows 10 (84)
    背水一战 Windows 10 (83)
    背水一战 Windows 10 (82)
    背水一战 Windows 10 (81)
  • 原文地址:https://www.cnblogs.com/phile/p/4490782.html
Copyright © 2011-2022 走看看