• bzoj1146


    这是一道无比繁琐的题目
    话说这道题使我第一次练dfs序,比较感动;
    首先dfs序就是在dfs过程中按照访问的顺序给每个点标上两个“时间戳”
    一个是第一次访问到点i时的时间戳c[i],一个是访问完以i为根时的时间戳cc[i]
    根据c[i],我们就可以将树变成序列,并且以i为根的子树,是序列上连续的一段
    当进行单点修改时,我们可以用树状数组前缀和维护树上的点到根路径上所有点的修改情况和;
    比如当点i修改时(比如+1) 则w[c[i]]+1,w[cc[i]]-1
    然后这道题显然是要在dfs序上套带修改的主席树,根据bzoj2588的经验我们很好解决这个问题
    由于修改的点要离散化,已经离线了,干脆用lca-tarjan求lca好了
    由于空间卡的比较严,所以我们不能直接树状数组+主席树
    而要先把原树建成主席树,然后修改的时候新建一棵主席树,用树状数组+主席树解决

      1 const maxn=80001;
      2 
      3 type node=record
      4        po,next:longint;
      5      end;
      6      link=record
      7        l,r,s:longint;
      8      end;
      9      point=record
     10        x,y,z:longint;
     11      end;
     12      qu=record
     13        num,loc,next:longint;
     14      end;
     15 
     16 
     17 var tree:array[0..10000010] of link;
     18     q:array[0..80010] of point;
     19     w:array[0..160010] of node;
     20     que:array[0..160010] of qu;
     21     v:array[0..80010] of boolean;
     22     e:array[0..4] of longint;
     23     g,fa,an,loc,d1,d2,ph,h,cc,c,b:array[0..80010] of longint;
     24     st:array[0..80010,0..4] of longint;
     25     sa,a:array[0..160010] of longint;
     26     j,k,t,tot,num,len,x,y,z,i,p,s,n,m:longint;
     27 
     28 function lowbit(x:longint):longint;
     29   begin
     30     exit(x and (-x));
     31   end;
     32 
     33 procedure update(x:longint);
     34   begin
     35     tree[x].s:=tree[tree[x].l].s+tree[tree[x].r].s;
     36   end;
     37 
     38 procedure add(x,y:longint);
     39   begin
     40     inc(len);
     41     w[len].po:=y;
     42     w[len].next:=d1[x];
     43     d1[x]:=len;
     44   end;
     45 
     46 procedure addq(x,y,z:longint);
     47   begin
     48     inc(num);
     49     que[num].num:=y;
     50     que[num].loc:=z;
     51     que[num].next:=d2[x];
     52     d2[x]:=num;
     53   end;
     54 
     55 function find(x:longint):longint;
     56   var l,r,m:longint;
     57   begin
     58     l:=1;
     59     r:=p;
     60     while l<=r do
     61     begin
     62       m:=(l+r) shr 1;
     63       if sa[m]=x then exit(m);
     64       if sa[m]>x then r:=m-1 else l:=m+1;
     65     end;
     66   end;
     67 
     68 function getf(x:longint):longint;
     69   begin
     70     if a[x]<>x then a[x]:=getf(a[x]);
     71     exit(a[x]);
     72   end;
     73 
     74 procedure dfs(x:longint);
     75   var i,y:longint;
     76   begin
     77     i:=d1[x];
     78     v[x]:=true;
     79     inc(tot);
     80     b[tot]:=x;  //b表示序列上的点对应的树上的哪个点
     81     c[x]:=tot;
     82     while i<>0 do
     83     begin
     84       y:=w[i].po;
     85       if not v[y] then
     86       begin
     87         fa[y]:=x;
     88         dfs(y);
     89         a[y]:=x;
     90       end;
     91       i:=w[i].next;
     92     end;
     93     cc[x]:=tot;
     94     i:=d2[x];
     95     while i<>0 do
     96     begin
     97       y:=que[i].num;
     98       if v[y] and (an[que[i].loc]=0) then  //lca-tarjan
     99         an[que[i].loc]:=getf(y);
    100       i:=que[i].next;
    101     end;
    102   end;
    103 
    104 procedure sort(l,r: longint);
    105   var i,j,x,y: longint;
    106   begin
    107     i:=l;
    108     j:=r;
    109     x:=a[(l+r) div 2];
    110     repeat
    111       while a[i]<x do inc(i);
    112       while x<a[j] do dec(j);
    113       if not(i>j) then
    114       begin
    115         y:=a[i];
    116         a[i]:=a[j];
    117         a[j]:=y;
    118         inc(i);
    119         j:=j-1;
    120       end;
    121     until i>j;
    122     if l<j then sort(l,j);
    123     if i<r then sort(i,r);
    124   end;
    125 
    126 function build(l,r:longint):longint;
    127   var m,q:longint;
    128   begin
    129     inc(t);
    130     if l=r then exit(t)
    131     else begin
    132       q:=t;
    133       m:=(l+r) shr 1;
    134       tree[q].l:=build(l,m);
    135       tree[q].r:=build(m+1,r);
    136       exit(q);
    137     end;
    138   end;
    139 
    140 function insert(last,x,l,r,z:longint):longint;
    141   var m,q:longint;
    142   begin
    143     inc(t);
    144     if l=r then
    145     begin
    146       tree[t].s:=tree[last].s+z;
    147       exit(t);
    148     end
    149     else begin
    150       m:=(l+r) shr 1;
    151       q:=t;
    152       if x<=m then
    153       begin
    154         tree[q].r:=tree[last].r;
    155         last:=tree[last].l;
    156         tree[q].l:=insert(last,x,l,m,z);
    157       end
    158       else begin
    159         tree[q].l:=tree[last].l;
    160         last:=tree[last].r;
    161         tree[q].r:=insert(last,x,m+1,r,z);
    162       end;
    163       update(q);
    164       exit(q);
    165     end;
    166   end;
    167 
    168 procedure work(i,x,z:longint);
    169   begin
    170     while i<=n do  //树状数组+主席树
    171     begin
    172       h[i]:=insert(h[i],x,1,p,z);  
    173       i:=i+lowbit(i);
    174     end;
    175   end;
    176 
    177 procedure get(x,y:longint);
    178   var i:longint;
    179   begin
    180     e[y]:=1;
    181     st[1,y]:=ph[x];
    182     i:=x;
    183     while i>0 do
    184     begin
    185       if h[i]<>0 then
    186       begin
    187         inc(e[y]);
    188         st[e[y],y]:=h[i];
    189       end;
    190       i:=i-lowbit(i);
    191     end;
    192   end;
    193 
    194 function sum:longint;
    195   var i,j:longint;
    196   begin
    197     sum:=0;
    198     for j:=1 to 4 do
    199       for i:=1 to e[j] do
    200         if (j<=2) then
    201           sum:=sum+tree[tree[st[i,j]].r].s
    202         else sum:=sum-tree[tree[st[i,j]].r].s;//u,v路径上的情况为tree[u]+tree[v]-tree[lca(u,v)]-tree[fa[lca(u,v)]];
    203   end;
    204 
    205 function getans(l,r,k:longint):longint;
    206   var m,s,i,j:longint;
    207   begin
    208     if l=r then exit(sa[l])
    209     else begin
    210       m:=(l+r) shr 1;
    211       s:=sum;
    212       if s>=k then
    213       begin
    214         for j:=1 to 4 do
    215           for i:=1 to e[j] do
    216             st[i,j]:=tree[st[i,j]].r;
    217         exit(getans(m+1,r,k));
    218       end
    219       else begin
    220         k:=k-s;
    221         for j:=1 to 4 do
    222           for i:=1 to e[j] do
    223             st[i,j]:=tree[st[i,j]].l;
    224         exit(getans(l,m,k));
    225       end;
    226     end;
    227   end;
    228 
    229 begin
    230   readln(n,m);
    231   for i:=1 to n do
    232   begin
    233     read(g[i]);
    234     a[i]:=g[i];
    235   end;
    236   s:=n;
    237   for i:=1 to n-1 do
    238   begin
    239     readln(x,y);
    240     add(x,y);
    241     add(y,x);
    242   end;
    243 
    244   for i:=1 to m do
    245   begin
    246     readln(q[i].z,q[i].x,q[i].y);
    247     if q[i].z=0 then
    248     begin
    249       inc(s);
    250       a[s]:=q[i].y;
    251     end
    252     else begin
    253       addq(q[i].x,q[i].y,i);
    254       addq(q[i].y,q[i].x,i);
    255     end;
    256   end;
    257   sort(1,s);
    258   p:=1;
    259   sa[1]:=a[1];
    260   for i:=2 to s do
    261     if a[i]<>a[i-1] then  //离散化
    262     begin
    263       inc(p);
    264       sa[p]:=a[i];
    265     end;
    266 
    267   for i:=1 to n do
    268     a[i]:=i;
    269   dfs(1);
    270   t:=0;
    271   h[0]:=build(1,p);
    272   ph[0]:=h[0];
    273   for i:=1 to n do
    274   begin
    275     loc[i]:=find(g[b[i]]);
    276     y:=fa[b[i]];
    277     ph[i]:=insert(ph[c[y]],loc[i],1,p,1);  //建立未修改前的主席树
    278   end;
    279   for i:=1 to m do
    280   begin
    281     if q[i].z<>0 then
    282     begin
    283       z:=an[i];
    284       get(c[q[i].x],1);  //提取区间
    285       get(c[q[i].y],2);
    286       get(c[z],3);
    287       get(c[fa[z]],4);
    288       s:=0;
    289       for j:=1 to 4 do
    290       begin
    291         for k:=1 to e[j] do
    292           if (j<=2) then
    293             s:=s+tree[st[k,j]].s
    294           else s:=s-tree[st[k,j]].s;
    295       end;
    296       if s<q[i].z then writeln('invalid request!')
    297       else writeln(getans(1,p,q[i].z));
    298     end
    299     else begin
    300       x:=q[i].x;
    301       work(c[x],loc[c[x]],-1);
    302       work(cc[x]+1,loc[c[x]],1);
    303       loc[c[x]]:=find(q[i].y);
    304       work(c[x],loc[c[x]],1);
    305       work(cc[x]+1,loc[c[x]],-1);
    306     end;
    307   end;
    308 end.
    View Code
  • 相关阅读:
    数据结构_bubble_sort
    数据结构_sfdg(小F打怪)
    数据结构_yjjsj(伊姐姐数字游戏)
    数据结构 queue
    数据结构 Job
    数据结构 happiness
    数据结构_calculator
    js并归排序的思路
    js神秘的电报密码---哈弗曼编码
    js同时获得数组的两个最小值
  • 原文地址:https://www.cnblogs.com/phile/p/4473091.html
Copyright © 2020-2023  润新知