• bzoj4817: [Sdoi2017]树点涂色


    4817: [Sdoi2017]树点涂色

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 435  Solved: 250
    [Submit][Status][Discuss]

    Description

    Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路
    径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作:
    1 x:
    把点x到根节点的路径上所有的点染上一种没有用过的新颜色。
    2 x y:
    求x到y的路径的权值。
    3 x y:
    在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。
    Bob一共会进行m次操作
     

    Input

    第一行两个数n,m。
    接下来n-1行,每行两个数a,b,表示a与b之间有一条边。
    接下来m行,表示操作,格式见题目描述
    1<=n,m<=100000
     

    Output

    每当出现2,3操作,输出一行。
    如果是2操作,输出一个数表示路径的权值
    如果是3操作,输出一个数表示权值的最大值
     

    Sample Input

    5 6
    1 2
    2 3
    3 4
    3 5
    2 4 5
    3 3
    1 4
    2 4 5
    1 5
    2 4 5

    Sample Output

    3
    4
    2
    2

    题解

      我们用实边代表边两端颜色相同,虚边代表两端颜色不同,1操作就是一次access的过程。

      在dfs序上,我们用线段树维护每个点到根路径上的虚边数目,一开始每个点的值都是自己的深度。每次access虚实边转换的时候,我们就把由实变虚的边整个子树的值+1,由虚变实的边整个子树的值-1。

      2操作就是u的值+v的值-2*lca(u,v)的值+1。

      3操作就是区间求max

      1 program j01;
      2 const maxn=100086;
      3 var t:array[0..maxn]of record son:array[0..1]of longint;fa:longint; end;
      4     f:array[0..4*maxn]of record tag,mx:longint; end;
      5     st:array[0..20,0..2*maxn]of longint;
      6     dep,home,dfn,ed,id,fir:array[0..maxn]of longint;
      7     q,next,bin:array[0..2*maxn]of longint;
      8     head:array[0..maxn]of longint;
      9     u,v,op,n,m,i,tt,tot,time,lc:longint;
     10     ll,rr,dd:longint;
     11     
     12 procedure swap(var a,b:longint);inline;var c:longint;begin c:=a;a:=b;b:=c; end;
     13 function max(a,b:longint):longint;inline;begin if a>b then exit(a) else exit(b); end;
     14 procedure addd(var h:longint;v:longint);inline;begin inc(tt);q[tt]:=v;next[tt]:=h;h:=tt; end;
     15 
     16 procedure dfs(i:longint);
     17 var j:longint;
     18 begin
     19     inc(tot);dfn[i]:=tot;id[tot]:=i;
     20     inc(time);st[0,time]:=i;fir[i]:=time;
     21     j:=head[i];
     22     while j>0 do
     23     begin
     24         if(q[j]<>t[i].fa)then
     25         begin
     26             dep[q[j]]:=dep[i]+1;t[q[j]].fa:=i;
     27             dfs(q[j]);inc(time);st[0,time]:=i;
     28         end;
     29         j:=next[j];
     30     end;
     31     ed[i]:=tot;
     32 end;
     33 {segement tree-------------------------------------------------------}
     34 
     35 procedure build(i,l,r:longint);
     36 var mid:longint;
     37 begin
     38     f[i].tag:=0;if l=r then begin f[i].mx:=dep[id[l]]; exit; end;
     39     mid:=(l+r)div 2;build(i*2,l,mid);build(i*2+1,mid+1,r);f[i].mx:=max(f[i*2].mx,f[i*2+1].mx);
     40 end;
     41 
     42 procedure pushdown(i:longint);
     43 var tag:longint;
     44 begin
     45     if f[i].tag=0 then exit;tag:=f[i].tag;f[i].tag:=0;
     46     inc(f[i*2].tag,tag);inc(f[i*2].mx,tag);
     47     inc(f[i*2+1].tag,tag);inc(f[i*2+1].mx,tag);
     48 end;
     49 
     50 procedure change(i,l,r:longint);
     51 var mid:longint;
     52 begin
     53     if(ll<=l)and(r<=rr)then begin inc(f[i].tag,dd);inc(f[i].mx,dd);exit; end;
     54     mid:=(l+r)div 2;pushdown(i);
     55     if ll<=mid then change(i*2,l,mid);
     56     if mid+1<=rr then change(i*2+1,mid+1,r);
     57     f[i].mx:=max(f[i*2].mx,f[i*2+1].mx);
     58 end;
     59 
     60 function find(i,l,r,ps:longint):longint;
     61 var mid:longint;
     62 begin
     63     if l=r then exit(f[i].mx);
     64     mid:=(l+r)div 2;pushdown(i);
     65     if ps<=mid then exit(find(i*2,l,mid,ps)) else exit(find(i*2+1,mid+1,r,ps));
     66 end;
     67 
     68 function ask(i,l,r:longint):longint;
     69 var mid,res:longint;
     70 begin
     71     if(ll<=l)and(r<=rr)then exit(f[i].mx);
     72     mid:=(l+r)div 2;pushdown(i);res:=0;
     73     if ll<=mid then res:=max(res,ask(i*2,l,mid));
     74     if mid+1<=rr then res:=max(res,ask(i*2+1,mid+1,r));
     75     exit(res);
     76 end;
     77 
     78 {segment tree--------------------------------------------------------}
     79 
     80 {st_lca--------------------------------------------------------------}
     81 
     82 function min_st(a,b:longint):longint;inline;begin if dep[a]<dep[b] then exit(a) else exit(b); end;
     83 
     84 procedure getst;
     85 var i,j:longint;
     86 begin
     87     bin[1]:=0;
     88     for i:=2 to time do
     89         if i and(i-1)=0 then bin[i]:=bin[i-1]+1 else bin[i]:=bin[i-1];
     90     for i:=1 to bin[time] do
     91         for j:=1 to time+1-(1 shl i) do 
     92             st[i,j]:=min_st(st[i-1,j],st[i-1,j+(1 shl (i-1))]);
     93 end;
     94 
     95 function lca(u,v:longint):longint;
     96 var k:longint;
     97 begin
     98     u:=fir[u];v:=fir[v];
     99     if u>v then swap(u,v);k:=bin[v-u+1];
    100     exit(min_st(st[k,u],st[k,v+1-(1 shl k)]));
    101 end;
    102 
    103 {st_lca--------------------------------------------------------------}
    104 
    105 {lct-----------------------------------------------------------------}
    106 
    107 function isroot(i:longint):boolean;inline;begin exit((t[t[i].fa].son[0]<>i)and(t[t[i].fa].son[1]<>i));end;
    108 
    109 procedure rotate(i,dd:longint);
    110 var k,l:longint;
    111 begin
    112     k:=t[i].son[dd];l:=t[i].fa;
    113     if not isroot(i) then t[l].son[ord(t[l].son[1]=i)]:=k;t[k].fa:=l;
    114     t[i].son[dd]:=t[k].son[1-dd];t[t[k].son[1-dd]].fa:=i;
    115     t[k].son[1-dd]:=i;t[i].fa:=k;
    116 end;
    117 
    118 procedure splay(i:longint);
    119 var p,dd:longint;
    120 begin
    121     while not isroot(i) do
    122     begin
    123         p:=t[i].fa;
    124         if isroot(p) then begin rotate(p,ord(t[p].son[1]=i));break; end;
    125         dd:=ord(t[t[p].fa].son[1]=p);
    126         if t[p].son[dd]=i then rotate(t[p].fa,dd) else rotate(t[i].fa,1-dd);
    127         rotate(t[i].fa,dd);
    128     end;
    129 end;
    130 
    131 function findmn(i:longint):longint;
    132 begin
    133     if i=0 then exit(0);
    134     while t[i].son[0]>0 do i:=t[i].son[0];exit(i);
    135 end;
    136 
    137 procedure access(x:longint);
    138 var y,u:longint;
    139 begin
    140     y:=0;
    141     while x>0 do
    142     begin
    143         splay(x);u:=findmn(t[x].son[1]);
    144         if u>0 then begin ll:=dfn[u];rr:=ed[u];dd:=1;change(1,1,n); end;
    145         t[x].son[1]:=y;u:=findmn(y);
    146         if u>0 then begin ll:=dfn[u];rr:=ed[u];dd:=-1;change(1,1,n); end;
    147         y:=x;x:=t[x].fa;
    148     end;
    149 end;
    150 
    151 {lct-----------------------------------------------------------------}
    152     
    153 begin
    154     assign(input,'1.in');reset(input);
    155     readln(n,m);
    156     fillchar(head,sizeof(head),0);tt:=0;
    157     for i:=1 to n-1 do
    158     begin
    159         readln(u,v);addd(head[u],v);addd(head[v],u);
    160     end;
    161     dep[1]:=0;t[1].fa:=0;time:=0;tot:=0;dfs(1);
    162     build(1,1,n);getst;
    163     for i:=1 to m do
    164     begin
    165         read(op);
    166         if op=1 then
    167         begin
    168             readln(u);access(u);
    169         end;
    170         if op=2 then
    171         begin
    172             readln(u,v);lc:=lca(u,v);
    173             writeln(find(1,1,n,dfn[u])+find(1,1,n,dfn[v])-2*find(1,1,n,dfn[lc])+1);
    174         end;
    175         if op=3 then
    176         begin
    177             readln(u);ll:=dfn[u];rr:=ed[u];
    178             writeln(ask(1,1,n)+1);
    179         end;
    180     end;
    181     close(input);
    182 end.
    View Code
  • 相关阅读:
    为什么要使用MQ消息中间件?
    趣图:这是招聘超神级别的程序员?
    基于redis的分布式锁的分析与实践
    我的java问题排查工具单
    趣图:看到这些窗户,我想插上几根网线
    SpringBoot+MyBatis+MySQL读写分离(实例)
    IntelliJ IDEA 常用快捷键
    ex3 多分类和神经网络
    9、神经网络的学习
    神经网络--反向传播详细推导过程
  • 原文地址:https://www.cnblogs.com/oldjang/p/7000035.html
Copyright © 2020-2023  润新知