zoukankan      html  css  js  c++  java
  • 【BZOJ2243】染色(树链剖分)

    题意:

    给定一棵有n个节点的无根树和m个操作,操作有2类:

    1、将节点a到节点b路径上所有点都染成颜色c;

    2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。

    请你写一个程序依次完成这m个操作。

    数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

    思路:树上的路径染色问题可以用树剖解决。

            对于线段树的某个节点我们记录以下信息:最左端颜色,最右端颜色,整段中段数,以及lazytag。

            其中lazytag>=0时表示该区间要改成什么颜色,-1表示当前节点没有标记。

            转换到树上做即可

            BZOJ过了样例就一遍过(萎靡)

      1 type un=record
      2          l,r,s,tag:longint;
      3         end;
      4 var t:array[1..500000]of un;
      5     f:array[1..110000,0..18]of longint;
      6     head,vet,next,flag,dep,fa,top,
      7     tid,id,size,son,a:array[1..210000]of longint;
      8     n,m,i,j,k,x,y,z,q,tot,time:longint;
      9     ch:string;
     10     emp:un;
     11 
     12 procedure swap(var x,y:longint);
     13 var t:longint;
     14 begin
     15  t:=x; x:=y; y:=t;
     16 end;
     17 
     18 procedure add(a,b:longint);
     19 begin
     20  inc(tot);
     21  next[tot]:=head[a];
     22  vet[tot]:=b;
     23  head[a]:=tot;
     24 end;
     25 
     26 procedure dfs1(u:longint);
     27 var e,v,maxsize,i:longint;
     28 begin
     29  flag[u]:=1; size[u]:=1; maxsize:=0; son[u]:=0;
     30  for i:=1 to 18 do
     31  begin
     32   if dep[u]<(1<<i) then break;
     33   f[u,i]:=f[f[u,i-1],i-1];
     34  end;
     35 
     36  e:=head[u];
     37  while e<>0 do
     38  begin
     39   v:=vet[e];
     40   if flag[v]=0 then
     41   begin
     42    dep[v]:=dep[u]+1;
     43    f[v,0]:=u;
     44    fa[v]:=u;
     45    dfs1(v);
     46    size[u]:=size[u]+size[v];
     47    if size[v]>maxsize then
     48    begin
     49     maxsize:=size[v];
     50     son[u]:=v;
     51    end;
     52   end;
     53   e:=next[e];
     54  end;
     55 end;
     56 
     57 procedure dfs2(u,ance:longint);
     58 var e,v:longint;
     59 begin
     60  flag[u]:=1; inc(time); tid[u]:=time; id[time]:=u; top[u]:=ance;
     61  if son[u]>0 then dfs2(son[u],ance);
     62  e:=head[u];
     63  while e<>0 do
     64  begin
     65   v:=vet[e];
     66   if flag[v]=0 then dfs2(v,v);
     67   e:=next[e];
     68  end;
     69 end;
     70 
     71 function lca(x,y:longint):longint;
     72 var i,d:longint;
     73 begin
     74  if dep[x]<dep[y] then swap(x,y);
     75  d:=dep[x]-dep[y];
     76  for i:=0 to 18 do
     77   if d and (1<<i)>0 then x:=f[x,i];
     78  for i:=18 downto 0 do
     79   if f[x,i]<>f[y,i] then
     80   begin
     81    x:=f[x,i]; y:=f[y,i];
     82   end;
     83  if x=y then exit(x);
     84  exit(f[x,0]);
     85 end;
     86 
     87 procedure pushup(p:longint);
     88 begin
     89  t[p].l:=t[p<<1].l; t[p].r:=t[p<<1+1].r;
     90  if t[p<<1].r<>t[p<<1+1].l then t[p].s:=t[p<<1].s+t[p<<1+1].s
     91   else t[p].s:=t[p<<1].s+t[p<<1+1].s-1;
     92 end;
     93 
     94 procedure pushdown(p,l,r:longint);
     95 var tmp:longint;
     96 begin
     97  tmp:=t[p].tag; t[p].tag:=-1;
     98  if (tmp=-1)or(l=r) then exit;
     99  t[p<<1].s:=1; t[p<<1+1].s:=1;
    100  t[p<<1].tag:=tmp; t[p<<1+1].tag:=tmp;
    101  t[p<<1].l:=tmp; t[p<<1].r:=tmp;
    102  t[p<<1+1].l:=tmp; t[p<<1+1].r:=tmp;
    103 end;
    104 
    105 procedure build(l,r,p:longint);
    106 var mid:longint;
    107 begin
    108  if l=r then
    109  begin
    110   t[p].s:=1;
    111   t[p].tag:=-1;
    112   exit;
    113  end;
    114  t[p].tag:=-1;
    115  mid:=(l+r)>>1;
    116  build(l,mid,p<<1);
    117  build(mid+1,r,p<<1+1);
    118 end;
    119 
    120 procedure update(l,r,x,y,v,p:longint);
    121 var mid:longint;
    122 begin
    123  pushdown(p,l,r);
    124  if (l>=x)and(r<=y) then
    125  begin
    126   t[p].l:=v; t[p].r:=v;
    127   t[p].s:=1; t[p].tag:=v;
    128   exit;
    129  end;
    130  mid:=(l+r)>>1;
    131  if x<=mid then update(l,mid,x,y,v,p<<1);
    132  if y>mid then update(mid+1,r,x,y,v,p<<1+1);
    133  pushup(p);
    134 end;
    135 
    136 function query(l,r,x,y,p:longint):longint;
    137 var mid,t1,t2:longint;
    138 begin
    139  pushdown(p,l,r);
    140  if (l>=x)and(r<=y) then exit(t[p].s);
    141  mid:=(l+r)>>1;
    142  t1:=0; t2:=0;
    143  if x<=mid then t1:=query(l,mid,x,y,p<<1);
    144  if y>mid then t2:=query(mid+1,r,x,y,p<<1+1);
    145  if t1=0 then exit(t2);
    146  if t2=0 then exit(t1);
    147  query:=t1+t2;
    148  if t[p<<1].r=t[p<<1+1].l then dec(query);
    149 end;
    150 
    151 function get(l,r,x,p:longint):longint;
    152 var mid:longint;
    153 begin
    154  pushdown(p,l,r);
    155  if (l=x)and(r=x) then exit(t[p].l);
    156  mid:=(l+r)>>1;
    157  if x<=mid then exit(get(l,mid,x,p<<1))
    158   else exit(get(mid+1,r,x,p<<1+1));
    159 end;
    160 
    161 function ask(x,y:longint):longint;
    162 var q:longint;
    163 begin
    164  q:=lca(x,y);
    165  ask:=0;
    166  while top[x]<>top[q] do
    167  begin
    168   ask:=ask+query(1,n,tid[top[x]],tid[x],1);
    169   if get(1,n,tid[top[x]],1)=get(1,n,tid[fa[top[x]]],1) then dec(ask);
    170   x:=fa[top[x]];
    171  end;
    172  ask:=ask+query(1,n,tid[q],tid[x],1);
    173  while top[y]<>top[q] do
    174  begin
    175   ask:=ask+query(1,n,tid[top[y]],tid[y],1);
    176   if get(1,n,tid[top[y]],1)=get(1,n,tid[fa[top[y]]],1) then dec(ask);
    177   y:=fa[top[y]];
    178  end;
    179  ask:=ask+query(1,n,tid[q],tid[y],1);
    180  dec(ask);
    181 
    182 end;
    183 
    184 procedure solve(x,y,z:longint);
    185 var q:longint;
    186 begin
    187  q:=lca(x,y);
    188  while top[x]<>top[q] do
    189  begin
    190   update(1,n,tid[top[x]],tid[x],z,1);
    191   x:=fa[top[x]];
    192  end;
    193  update(1,n,tid[q],tid[x],z,1);
    194  while top[y]<>top[q] do
    195  begin
    196   update(1,n,tid[top[y]],tid[y],z,1);
    197   y:=fa[top[y]];
    198  end;
    199  update(1,n,tid[q],tid[y],z,1);
    200 end;
    201 
    202 begin
    203  assign(input,'bzoj2243.in'); reset(input);
    204  assign(output,'bzoj2243.out'); rewrite(output);
    205  readln(n,m);
    206  for i:=1 to n do read(a[i]);
    207  for i:=1 to n-1 do
    208  begin
    209   readln(x,y);
    210   add(x,y);
    211   add(y,x);
    212  end;
    213  dfs1(1);
    214  fillchar(flag,sizeof(flag),0);
    215  dfs2(1,1);
    216  build(1,n,1);
    217  for i:=1 to n do update(1,n,tid[i],tid[i],a[i],1);
    218  //for i:=1 to n do write(a[id[i]],' ');
    219  for i:=1 to m do
    220  begin
    221   readln(ch);
    222   x:=0; y:=0; z:=0;
    223   case ch[1] of
    224    'C':
    225    begin
    226     for k:=3 to length(ch) do
    227     begin
    228      if ch[k]=' ' then break;
    229      x:=x*10+ord(ch[k])-ord('0');
    230     end;
    231     j:=k+1;
    232     for k:=j to length(ch) do
    233     begin
    234      if ch[k]=' ' then break;
    235      y:=y*10+ord(ch[k])-ord('0');
    236     end;
    237     j:=k+1;
    238     for k:=j to length(ch) do z:=z*10+ord(ch[k])-ord('0');
    239     solve(x,y,z);
    240    end;
    241 
    242    'Q':
    243    begin
    244     for k:=3 to length(ch) do
    245     begin
    246      if ch[k]=' ' then break;
    247      x:=x*10+ord(ch[k])-ord('0');
    248     end;
    249     j:=k+1;
    250     for k:=j to length(ch) do y:=y*10+ord(ch[k])-ord('0');
    251     writeln(ask(x,y));
    252    end;
    253   end;
    254  end;
    255  close(input);
    256  close(output);
    257 end.
  • 相关阅读:
    The 2014 ACM-ICPC Asia Xi'an Regional Contest — F题 Color
    CodeForces 358D — Dima and Hares
    VIJOS国庆节模拟赛之繁星春水
    两个算法
    HDU 4901
    Andrew Stankevich Contests #2
    HDU 4701
    HDU 5033
    程序安装出现错误代码为2869
    常用正则表达式总结(以后加了再补充)
  • 原文地址:https://www.cnblogs.com/myx12345/p/6115301.html
Copyright © 2011-2022 走看看