• bzoj2243


    很明显是树链剖分吧
    然后很明显要用线段树维护吧,即维护一段区间首、尾颜色和区间内颜色总数
    然后修改lazy tag弄一弄,查询注意这一段尾和下一段首的颜色可能相同
    然后就没什么了

      1 type node=record
      2        po,next:longint;
      3      end;
      4      link=record
      5        l,r,s:longint;
      6      end;
      7 
      8 var tree:array[0..400010] of link;
      9     lazy:array[0..400010] of longint;
     10     w:array[0..200010] of node;
     11     top,fa,d,size,a,b,c,p:array[0..100010] of longint;
     12     cas,i,n,m,x,y,z,len,t,prf,plf,rf,lf:longint;
     13     ch:char;
     14 
     15 procedure swap(var a,b:longint);
     16   var c:longint;
     17   begin
     18     c:=a;
     19     a:=b;
     20     b:=c;
     21   end;
     22 
     23 procedure add(x,y:longint);
     24   begin
     25     inc(len);
     26     w[len].po:=y;
     27     w[len].next:=p[x];
     28     p[x]:=len;
     29   end;
     30 
     31 procedure dfs1(x:longint);
     32   var i,y:longint;
     33   begin
     34     size[x]:=1;
     35     i:=p[x];
     36     while i<>0 do
     37     begin
     38       y:=w[i].po;
     39       if fa[x]<>y then
     40       begin
     41         d[y]:=d[x]+1;
     42         fa[y]:=x;
     43         dfs1(y);
     44         size[x]:=size[x]+size[y];
     45       end;
     46       i:=w[i].next;
     47     end;
     48   end;
     49 
     50 procedure dfs2(x:longint);
     51   var q,i,y:longint;
     52   begin
     53     i:=p[x];
     54     q:=0;
     55     inc(t);
     56     c[x]:=t;
     57     b[t]:=x;
     58     while i<>0 do
     59     begin
     60       y:=w[i].po;
     61       if fa[x]<>y then
     62         if size[q]<size[y] then q:=y;
     63       i:=w[i].next;
     64     end;
     65     if q<>0 then
     66     begin
     67       top[q]:=top[x];
     68       dfs2(q);
     69     end;
     70     i:=p[x];
     71     while i<>0 do
     72     begin
     73       y:=w[i].po;
     74       if top[y]=0 then
     75       begin
     76         top[y]:=y;
     77         dfs2(y);
     78       end;
     79       i:=w[i].next;
     80     end;
     81   end;
     82 
     83 procedure update(i:longint);
     84   begin
     85     tree[i].l:=tree[i*2].l;
     86     tree[i].r:=tree[i*2+1].r;
     87     tree[i].s:=tree[i*2].s+tree[i*2+1].s;
     88     if tree[i*2].r=tree[i*2+1].l then dec(tree[i].s);
     89   end;
     90 
     91 procedure build(i,l,r:longint);
     92   var m:longint;
     93   begin
     94     if l=r then
     95     begin
     96       tree[i].l:=a[b[l]];
     97       tree[i].r:=a[b[l]];
     98       tree[i].s:=1;
     99     end
    100     else begin
    101       m:=(l+r) shr 1;
    102       build(i*2,l,m);
    103       build(i*2+1,m+1,r);
    104       update(i);
    105     end;
    106   end;
    107 
    108 procedure push(i:longint);
    109   begin
    110     tree[i*2].l:=lazy[i];
    111     tree[i*2+1].l:=lazy[i];
    112     tree[i*2].r:=lazy[i];
    113     tree[i*2+1].r:=lazy[i];
    114     tree[i*2+1].s:=1;
    115     tree[i*2].s:=1;
    116     lazy[i*2]:=lazy[i];
    117     lazy[i*2+1]:=lazy[i];
    118     lazy[i]:=-1;
    119   end;
    120 
    121 procedure change(i,l,r,x,y,z:longint);
    122   var m:longint;
    123   begin
    124     if (x<=l) and (y>=r) then
    125     begin
    126       tree[i].l:=z;
    127       tree[i].r:=z;
    128       tree[i].s:=1;
    129       lazy[i]:=z;
    130     end
    131     else begin
    132       m:=(l+r) shr 1;
    133       if lazy[i]<>-1 then push(i);
    134       if x<=m then change(i*2,l,m,x,y,z);
    135       if y>m then change(i*2+1,m+1,r,x,y,z);
    136       update(i);
    137     end;
    138   end;
    139 
    140 procedure work(x,y,z:longint);
    141   var f1,f2:longint;
    142   begin
    143     f1:=top[x];
    144     f2:=top[y];
    145     while f1<>f2 do
    146     begin
    147       if d[f1]>=d[f2] then
    148       begin
    149         change(1,1,n,c[f1],c[x],z);
    150         x:=fa[f1];
    151       end
    152       else begin
    153         change(1,1,n,c[f2],c[y],z);
    154         y:=fa[f2];
    155       end;
    156       f1:=top[x];
    157       f2:=top[y];
    158     end;
    159     if c[x]>c[y] then swap(x,y);
    160     change(1,1,n,c[x],c[y],z);
    161   end;
    162 
    163 function getans(i,l,r,x,y:longint):longint;
    164   var m:longint;
    165   begin
    166     if (x<=l) and (y>=r) then getans:=tree[i].s
    167     else begin
    168       m:=(l+r) shr 1;
    169       if lazy[i]<>-1 then push(i);
    170       getans:=0;
    171       if x<=m then getans:=getans+getans(i*2,l,m,x,y);
    172       if y>m then getans:=getans+getans(i*2+1,m+1,r,x,y);
    173       if (x<=m) and (y>m) and (tree[i*2].r=tree[i*2+1].l) then
    174         getans:=getans-1;
    175     end;
    176     if l=x then
    177     begin
    178       if cas=1 then
    179         lf:=tree[i].l
    180       else rf:=tree[i].l;
    181     end;
    182     if r=y then t:=tree[i].r;
    183   end;
    184 
    185 function ask(x,y:longint):longint;
    186   var f1,f2,s:longint;
    187   begin
    188     f1:=top[x];
    189     f2:=top[y];
    190     s:=0;
    191     prf:=-1;
    192     plf:=-1;
    193     lf:=-1;
    194     rf:=-1;
    195     while f1<>f2 do
    196     begin
    197       if d[f1]>=d[f2] then
    198       begin
    199         cas:=1;
    200         s:=s+getans(1,1,n,c[f1],c[x]);
    201         if t=plf then dec(s); //维护x链的尾部
    202         plf:=lf;
    203         x:=fa[f1];
    204       end
    205       else begin
    206         cas:=2;
    207         s:=s+getans(1,1,n,c[f2],c[y]);
    208         if t=prf then dec(s);  //维护y链尾部
    209         prf:=rf;
    210         y:=fa[f2];
    211       end;
    212       f1:=top[x];
    213       f2:=top[y];
    214     end;
    215 
    216     if c[x]>c[y] then
    217     begin
    218       swap(x,y);
    219       swap(prf,plf);
    220     end;
    221     cas:=1;
    222     s:=s+getans(1,1,n,c[x],c[y]);
    223     if lf=plf then dec(s); //注意这里有两种情况
    224     if t=prf then dec(s);
    225     exit(s);
    226   end;
    227 
    228 begin
    229   readln(n,m);
    230   for i:=1 to n do
    231     read(a[i]);
    232   for i:=1 to n-1 do
    233   begin
    234     readln(x,y);
    235     add(x,y);
    236     add(y,x);
    237   end;
    238   d[1]:=1;
    239   dfs1(1);
    240   top[1]:=1;
    241   dfs2(1);
    242   build(1,1,n);
    243   fillchar(lazy,sizeof(lazy),255);
    244   for i:=1 to m do
    245   begin
    246     read(ch);
    247     if ch='C' then
    248     begin
    249       readln(x,y,z);
    250       work(x,y,z);
    251     end
    252     else begin
    253       readln(x,y);
    254       writeln(ask(x,y));
    255     end;
    256   end;
    257 end.
    View Code
  • 相关阅读:
    linux seqlock 锁
    linux 位操作
    linux 原子变量
    linux 读者/写者自旋锁
    linux自旋锁函数
    linux 自旋锁 API 简介
    linux Completions 机制
    linux 读者/写者旗标
    linux 在 scull 中使用旗标
    Linux 旗标实现
  • 原文地址:https://www.cnblogs.com/phile/p/4473089.html
Copyright © 2020-2023  润新知