zoukankan      html  css  js  c++  java
  • BZOJ2243: [SDOI2011]染色

    2243: [SDOI2011]染色

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 1934  Solved: 775
    [Submit][Status]

    Description

     

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

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

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

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

    Input

    第一行包含2个整数nm,分别表示节点数和操作数;

    第二行包含n个正整数表示n个节点的初始颜色

    下面 行每行包含两个整数xy,表示xy之间有一条无向边。

    下面 行每行描述一个操作:

    “C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括ab)都染成颜色c

    “Q a b”表示这是一个询问操作,询问节点a到节点b(包括ab)路径上的颜色段数量。

     

    Output

    对于每个询问操作,输出一行答案。

     

    Sample Input

    6 5

    2 2 1 2 1 1

    1 2

    1 3

    2 4

    2 5

    2 6

    Q 3 5

    C 2 1 1

    Q 3 5

    C 5 1 2

    Q 3 5

    Sample Output

    3

    1

    2

    HINT

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

    Source

    题解:
    强大的树链剖分!强大的线段树!
    原来统计一段序列被分为几段是可以分治的,一直想这个想了好久。。。
    通过这题,学到了几点:
    1.线段树
      pushdown操作是在查询到k,需要继续向下时调用
      pushup不管什么操作,完了之后调用一次
    2.树链剖分
       确认算法没错肯定是哪儿犯了sb错误。。。
      现在感觉树链剖分也是蛮好写的,虽然代码蛮长
    代码:
      1 {$M 10000000,0,maxlongint}
      2 const maxn=100000+100;
      3 type node1=record
      4      go,next:longint;
      5      end;
      6      node2=record
      7      l,r,lx,rx,num,mid,tag:longint;
      8      end;
      9 
     10 var  e:array[0..2*maxn] of node1;
     11      t:array[0..4*maxn] of node2;
     12      p,a,v,fa,s,head,dep,son,top:array[0..maxn] of longint;
     13      i,n,m,x,y,z,sz,ans,tot:longint;
     14      ch:char;
     15       procedure swap(var x,y:longint);
     16       var t:longint;
     17       begin
     18         t:=x;x:=y;y:=t;
     19       end;
     20      procedure insert(x,y:longint);
     21       begin
     22         inc(tot);
     23         e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
     24       end;
     25      function min(x,y:longint):longint;
     26       begin
     27         if x<y then exit(x) else exit(y);
     28       end;
     29      function max(x,y:longint):longint;
     30       begin
     31         if x>y then exit(x) else exit(y);
     32       end;
     33 procedure dfs1(x:longint);
     34  var i,j,y:longint;
     35  begin
     36    j:=0;s[x]:=1;
     37    i:=head[x];
     38    while i<>0 do
     39     begin
     40      y:=e[i].go;
     41      if dep[y]=0 then
     42        begin
     43          dep[y]:=dep[x]+1;
     44          fa[y]:=x;
     45          dfs1(y);
     46          inc(s[x],s[y]);
     47          if s[y]>s[j] then j:=y;
     48        end;
     49      i:=e[i].next;
     50     end;
     51    son[x]:=j;
     52  end;
     53 procedure dfs2(x,chain:longint);
     54  var i,y:longint;
     55  begin
     56    inc(sz);p[x]:=sz;top[x]:=chain;
     57    if son[x]<>0 then dfs2(son[x],chain);
     58    i:=head[x];
     59    while i<>0 do
     60      begin
     61       y:=e[i].go;
     62       if (y<>son[x]) and (y<>fa[x]) then dfs2(y,y);
     63       i:=e[i].next;
     64      end;
     65  end;
     66 procedure pushup(k:longint);
     67  begin
     68    with t[k] do
     69     begin
     70       num:=t[k<<1].num+t[k<<1+1].num-ord(t[k<<1].rx=t[k<<1+1].lx);
     71       lx:=t[k<<1].lx;rx:=t[k<<1+1].rx;
     72     end;
     73  end;
     74 
     75 procedure build(k,x,y:longint);
     76  begin
     77    with t[k] do
     78     begin
     79      l:=x;r:=y;mid:=(l+r)>>1;tag:=0;
     80      if l=r then begin lx:=a[l];rx:=a[l];num:=1;exit;end;
     81      build(k<<1,l,mid);build(k<<1+1,mid+1,r);
     82      pushup(k);
     83     end;
     84  end;
     85 
     86 procedure init;
     87  begin
     88    readln(n,m);
     89    for i:=1 to n do read(v[i]);readln;
     90    for i:=1 to n-1 do begin readln(x,y);insert(x,y);insert(y,x);end;
     91    dep[1]:=1;
     92    dfs1(1);
     93    dfs2(1,1);
     94    for i:=1 to n do a[p[i]]:=v[i];
     95    build(1,1,n);
     96  end;
     97 procedure same(k,val:longint);
     98  begin
     99    with t[k] do
    100     begin
    101      tag:=val;lx:=val;rx:=val;num:=1;
    102     end;
    103  end;
    104 
    105 procedure pushdown(k:longint);
    106  begin
    107    with t[k] do
    108     begin
    109      if (tag=0) or (l=r) then exit;
    110      same(k<<1,tag);same(k<<1+1,tag);
    111      tag:=0;
    112     end;
    113  end;
    114 
    115 procedure change(k,x,y,z:longint);
    116  begin
    117    with t[k] do
    118     begin
    119      pushdown(k);
    120      if (l=x) and (r=y) then begin same(k,z);exit;end;
    121      pushdown(k);
    122      if y<=mid then change(k<<1,x,y,z)
    123      else if x>mid then change(k<<1+1,x,y,z)
    124      else
    125        begin
    126          change(k<<1,x,mid,z);
    127          change(k<<1+1,mid+1,y,z);
    128        end;
    129      pushup(k);
    130     end;
    131  end;
    132 function query(k,x,y:longint):longint;
    133  begin
    134    with t[k] do
    135     begin
    136      if (l=x) and (r=y) then exit(num);
    137      pushdown(k);
    138      if y<=mid then exit(query(k<<1,x,y))
    139      else if x>mid then exit(query(k<<1+1,x,y))
    140      else exit(query(k<<1,x,mid)+query(k<<1+1,mid+1,y)-ord(t[k<<1].rx=t[k<<1+1].lx));
    141      pushup(k);
    142     end;
    143  end;
    144 function get(k,x:longint):longint;
    145  begin
    146    with t[k] do
    147     begin
    148      if l=r then exit(lx);
    149      pushdown(k);
    150      if x<=mid then exit(get(k<<1,x)) else exit(get(k<<1+1,x));
    151      pushup(k);
    152     end;
    153  end;
    154 
    155 procedure solvechange;
    156  begin
    157    readln(x,y,z);
    158    while top[x]<>top[y] do
    159      begin
    160       if dep[top[x]]<dep[top[y]] then swap(x,y);
    161       change(1,p[top[x]],p[x],z);
    162       x:=fa[top[x]];
    163      end;
    164    if dep[x]>dep[y] then swap(x,y);
    165    change(1,p[x],p[y],z);
    166  end;
    167 procedure getans;
    168  begin
    169    ans:=0;
    170    readln(x,y);
    171    while top[x]<>top[y] do
    172      begin
    173       if dep[top[x]]<dep[top[y]] then swap(x,y);
    174       inc(ans,query(1,p[top[x]],p[x]));
    175       dec(ans,ord(get(1,p[top[x]])=get(1,p[fa[top[x]]])));
    176       x:=fa[top[x]];
    177      end;
    178    if dep[x]>dep[y] then swap(x,y);
    179    inc(ans,query(1,p[x],p[y]));
    180    writeln(ans);
    181  end;
    182 
    183 procedure main;
    184  begin
    185    for i:=1 to m do
    186     begin
    187      read(ch);
    188      if ch='C' then solvechange
    189      else getans;
    190     end;
    191  end;
    192 begin
    193   assign(input,'input.txt');assign(output,'output.txt');
    194   reset(input);rewrite(output);
    195   init;
    196   main;
    197   close(input);close(output);
    198 end.                           
    View Code
  • 相关阅读:
    Excel操作 Microsoft.Office.Interop.Excel.dll的使用
    C#通过Microsoft.Office.Interop.Word操作Word
    Swift编码总结2
    Swift编码总结1
    Python第一阶段06
    Python第一阶段05
    Python第一阶段04
    Python第一阶段03
    Python第一阶段02
    Python第一阶段01
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3900051.html
Copyright © 2011-2022 走看看