• bzoj3626


    百度空间马上要下架的说,赶快把最后一点题解补完,然后搬家
    这是一道不错的题,首先注意询问是满足区间减法的,我们把他变成前缀和表示
    设我们询问[1,r]中的点和z的LCA深度和,假设我们确定一个根,不难发现一个有趣的事情
    点z和点i的LCA深度=z和i到根公共路径(LCA到根的路径)上点的个数!
    也就是说,当我们查询时,我们只要知道,[1,r]上的点到根路径上的点在z到根上出现的次数和
    所以不难想到离线的做法,按照编号的顺序,每次做到点i,就把点i到根路径上点权值+1
    询问的时候我们只要查询z到根路径上点权值和即可,显然我们可以用树链剖分+线段树维护

      1 const mo=201314;
      2 type node=record
      3        po,next:longint;
      4      end;
      5      que=record
      6        x,y,p,op:longint;
      7      end;
      8 
      9 var p,c,top,ans,fa,size:array[0..50010] of longint;
     10     tree,lazy:array[0..50010*4] of longint;
     11     q:array[0..100010] of que;
     12     e:array[0..50010] of node;
     13     t,l,r,x,i,j,n,m:longint;
     14 
     15 procedure swap(var a,b:que);
     16   var c:que;
     17   begin
     18     c:=a;
     19     a:=b;
     20     b:=c;
     21   end;
     22 
     23 procedure add(x,y:longint);
     24   begin
     25     e[i].po:=y;
     26     e[i].next:=p[x];
     27     p[x]:=i;
     28   end;
     29 
     30 procedure dfs1(x:longint);
     31   var i,y:longint;
     32   begin
     33     size[x]:=1;
     34     i:=p[x];
     35     while i<>0 do
     36     begin
     37       y:=e[i].po;
     38       fa[y]:=x;
     39       dfs1(y);
     40       size[x]:=size[x]+size[y];
     41       i:=e[i].next;
     42     end;
     43   end;
     44 
     45 procedure dfs2(x:longint);
     46   var i,y,q:longint;
     47   begin
     48     inc(t);
     49     c[x]:=t;
     50     q:=n+1;
     51     i:=p[x];
     52     while i<>0 do
     53     begin
     54       y:=e[i].po;
     55       if size[y]>size[q] then q:=y;
     56       i:=e[i].next;
     57     end;
     58     if q<>n+1 then
     59     begin
     60       top[q]:=top[x];
     61       dfs2(q);
     62     end;
     63     i:=p[x];
     64     while i<>0 do
     65     begin
     66       y:=e[i].po;
     67       if y<>q then
     68       begin
     69         top[y]:=y;
     70         dfs2(y);
     71       end;
     72       i:=e[i].next;
     73     end;
     74   end;
     75 
     76 procedure sort(l,r:longint);
     77   var i,j,y:longint;
     78   begin
     79     i:=l;
     80     j:=r;
     81     y:=q[(l+r) shr 1].y;
     82     repeat
     83       while q[i].y<y do inc(i);
     84       while y<q[j].y do dec(j);
     85       if not(i>j) then
     86       begin
     87         swap(q[i],q[j]);
     88         inc(i);
     89         dec(j);
     90       end;
     91     until i>j;
     92     if l<j then sort(l,j);
     93     if i<r then sort(i,r);
     94   end;
     95 
     96 procedure push(i,l,r:longint);
     97   var m:longint;
     98   begin
     99     m:=(l+r) shr 1;
    100     tree[i*2]:=tree[i*2]+lazy[i]*(m+1-l);
    101     tree[i*2+1]:=tree[i*2+1]+lazy[i]*(r-m);
    102     inc(lazy[i*2],lazy[i]);
    103     inc(lazy[i*2+1],lazy[i]);
    104     lazy[i]:=0;
    105   end;
    106 
    107 procedure work(i,l,r,x,y:longint);
    108   var m:longint;
    109   begin
    110     if (x<=l) and (y>=r) then
    111     begin
    112       tree[i]:=tree[i]+r-l+1;
    113       lazy[i]:=lazy[i]+1;
    114     end
    115     else begin
    116       if lazy[i]>0 then push(i,l,r);
    117       m:=(l+r) shr 1;
    118       if x<=m then work(i*2,l,m,x,y);
    119       if y>m then work(i*2+1,m+1,r,x,y);
    120       tree[i]:=(tree[i*2]+tree[i*2+1]) mod mo;
    121     end;
    122   end;
    123 
    124 function getans(i,l,r,x,y:longint):longint;
    125   var m,s:longint;
    126   begin
    127     if (x<=l) and (y>=r) then exit(tree[i])
    128     else begin
    129       if lazy[i]>0 then push(i,l,r);
    130       m:=(l+r) shr 1;
    131       s:=0;
    132       if x<=m then s:=s+getans(i*2,l,m,x,y);
    133       if y>m then s:=s+getans(i*2+1,m+1,r,x,y);
    134       exit(s);
    135     end;
    136   end;
    137 
    138 procedure ins(x:longint);
    139   begin
    140     while top[x]<>-1 do
    141     begin
    142       work(1,1,n,c[top[x]],c[x]);
    143       x:=fa[top[x]];
    144     end;
    145     work(1,1,n,1,c[x]);
    146   end;
    147 
    148 function ask(x:longint):longint;
    149   begin
    150     ask:=0;
    151     while top[x]<>-1 do
    152     begin
    153       ask:=ask+getans(1,1,n,c[top[x]],c[x]);
    154       x:=fa[top[x]];
    155     end;
    156     ask:=(ask+getans(1,1,n,1,c[x])) mod mo;
    157   end;
    158 
    159 begin
    160   readln(n,m);
    161   for i:=1 to n-1 do
    162   begin
    163     read(x);
    164     add(x,i);
    165   end;
    166   dfs1(0);
    167   top[0]:=-1;
    168   dfs2(0);
    169   t:=0;
    170   for i:=1 to m do
    171   begin
    172     readln(l,r,x);
    173     inc(t);
    174     q[t].x:=x; q[t].y:=l-1;
    175     q[t].p:=i; q[t].op:=-1;
    176     inc(t);
    177     q[t].x:=x; q[t].y:=r;
    178     q[t].p:=i; q[t].op:=1;
    179   end;
    180   sort(1,t);
    181   j:=0;
    182   for i:=1 to t do
    183   begin
    184     while (j<n) and (j<=q[i].y) do
    185     begin
    186       ins(j);
    187       inc(j);
    188     end;
    189     ans[q[i].p]:=(ans[q[i].p]+q[i].op*ask(q[i].x)+mo) mod mo;
    190   end;
    191   for i:=1 to m do
    192     writeln(ans[i]);
    193 end.
    View Code
  • 相关阅读:
    求1000以内的勾股数的算法流程图
    23天的单车旅行,从广州到四川,重庆,大足石刻,母校,家,发完了
    好玩的Flash:跟鼠标拼命
    23天的单车旅行,从广州到四川,息烽集中营,韩国人,乌江,遵义
    如何彻底删除SQL Server2005
    EOF,EOC与感叹号的区别
    如何彻底卸载vs2008及其组件?
    PHP中extract()函数的妙用
    php 函数合并 array_merge 与 + 的区别
    unserialize error at offset
  • 原文地址:https://www.cnblogs.com/phile/p/4472942.html
Copyright © 2020-2023  润新知