zoukankan      html  css  js  c++  java
  • bzoj3083 遥远的国度

    Description

    zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度。当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn完成任务后才能进入遥远的国度继续追杀。

    问题是这样的:遥远的国度有n个城市,这些城市之间由一些路连接且这些城市构成了一颗树。这个国度有一个首都,我们可以把这个首都看做整棵树的根,但遥远的国度比较奇怪,首都是随时有可能变为另外一个城市的。遥远的国度的每个城市有一个防御值,有些时候RapiD会使得某两个城市之间的路径上的所有城市的防御值都变为某个值。RapiD想知道在某个时候,如果把首都看做整棵树的根的话,那么以某个城市为根的子树的所有城市的防御值最小是多少。由于RapiD无法解决这个问题,所以他拦住了zcwwzdjn希望他能帮忙。但zcwwzdjn还要追杀sb的zhx,所以这个重大的问题就被转交到了你的手上。

    Input

    第1行两个整数n m,代表城市个数和操作数。
    第2行至第n行,每行两个整数 u v,代表城市u和城市v之间有一条路。
    第n+1行,有n个整数,代表所有点的初始防御值。
    第n+2行一个整数 id,代表初始的首都为id。
    第n+3行至第n+m+2行,首先有一个整数opt,如果opt=1,接下来有一个整数id,代表把首都修改为id;如果opt=2,接下来有三个整数p1 p2 v,代表将p1 p2路径上的所有城市的防御值修改为v;如果opt=3,接下来有一个整数 id,代表询问以城市id为根的子树中的最小防御值。

    Output


    对于每个opt=3的操作,输出一行代表对应子树的最小点权值。

    Sample Input

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

    Sample Output

    1
    2
    3
    4

    HINT

     对于20%的数据,n<=1000 m<=1000。
    对于另外10%的数据,n<=100000,m<=100000,保证修改为单点修改。
    对于另外10%的数据,n<=100000,m<=100000,保证树为一条链。
    对于另外10%的数据,n<=100000,m<=100000,没有修改首都的操作。
    对于100%的数据,n<=100000,m<=100000,0<所有权值<=2^31。

    Source

    zhonghaoxi提供

    分类讨论之后还是可以树链剖分的,不是很难想。

    写树链剖分的时候还错了一次,dfs的时候要判断不能再往一个点的父亲dfs(这个错误果然很sb)。

      1 program rrr(input,output);
      2 type
      3   etype=record
      4      t,next:longint;
      5   end;
      6   treetype=record
      7      l,r,min,d:longint;
      8   end;
      9 var
     10   a:array[0..400040]of treetype;
     11   e:array[0..200020]of etype;
     12   father:array[0..100010,0..17]of longint;
     13   b,c,q,dep,siz,son,ss,head,idx:array[0..100010]of longint;
     14   n,m,op,i,j,k,x,y,z,cnt,cap,h,t:longint;
     15 function min(a,b:longint):longint;
     16 begin
     17    if a<b then exit(a) else exit(b);
     18 end;
     19 procedure add(x,y:longint);
     20 begin
     21    inc(cnt);e[cnt].t:=y;e[cnt].next:=c[x];c[x]:=cnt;
     22 end;
     23 procedure dfs(k:longint);
     24 var
     25   i:longint;
     26 begin
     27    if son[k]=0 then exit;
     28    head[son[k]]:=head[k];inc(cnt);idx[son[k]]:=cnt;
     29    dfs(son[k]);
     30    i:=c[k];
     31    while i<>0 do
     32       begin
     33          if (e[i].t<>son[k]) and (e[i].t<>father[k,0]) then
     34             begin
     35                inc(cnt);idx[e[i].t]:=cnt;head[e[i].t]:=e[i].t;
     36                dfs(e[i].t);
     37             end;
     38          i:=e[i].next;
     39       end;
     40 end;
     41 procedure split;
     42 begin
     43    h:=0;t:=1;q[1]:=1;father[1,0]:=0;dep[1]:=1;
     44    while h<t do
     45       begin
     46          inc(h);i:=c[q[h]];
     47          while i<>0 do
     48             begin
     49                if e[i].t<>father[q[h],0] then
     50                   begin
     51                      father[e[i].t,0]:=q[h];dep[e[i].t]:=dep[q[h]]+1;
     52                      inc(t);q[t]:=e[i].t;
     53                   end;
     54                i:=e[i].next;
     55             end;
     56       end;
     57    fillchar(son,sizeof(son),0);fillchar(ss,sizeof(ss),0);
     58    for i:=1 to n do siz[i]:=1;
     59    for i:=n downto 1 do
     60       begin
     61          inc(siz[father[q[i],0]],siz[q[i]]);
     62          if siz[q[i]]>ss[father[q[i],0]] then begin ss[father[q[i],0]]:=siz[q[i]];son[father[q[i],0]]:=q[i]; end;
     63       end;
     64    for j:=1 to 16 do for i:=1 to n do father[i,j]:=father[father[i,j-1],j-1];
     65    cnt:=1;idx[1]:=1;head[1]:=1;
     66    dfs(1);
     67 end;
     68 procedure build(k,l,r:longint);
     69 var
     70   mid,i:longint;
     71 begin
     72    a[k].l:=l;a[k].r:=r;a[k].d:=0;
     73    if l=r then begin a[k].min:=b[l];exit; end;
     74    mid:=(l+r)>>1;i:=k+k;
     75    build(i,l,mid);build(i+1,mid+1,r);
     76    a[k].min:=min(a[i].min,a[i+1].min);
     77 end;
     78 procedure pushdown(k:longint);
     79 var
     80   i:longint;
     81 begin
     82    if a[k].l=a[k].r then a[k].d:=0;
     83    if a[k].d=0 then exit;
     84    i:=k+k;a[i].min:=a[k].d;a[i].d:=a[k].d;
     85    inc(i);a[i].min:=a[k].d;a[i].d:=a[k].d;
     86    a[k].d:=0;
     87 end;
     88 procedure change(k,x,y:longint);
     89 var
     90   mid,i:longint;
     91 begin
     92    pushdown(k);
     93    if (x<=a[k].l) and (a[k].r<=y) then begin a[k].min:=z;a[k].d:=z;exit; end;
     94    mid:=(a[k].l+a[k].r)>>1;i:=k+k;
     95    if x<=mid then change(i,x,y);
     96    if mid<y then change(i+1,x,y);
     97    a[k].min:=min(a[i].min,a[i+1].min);
     98 end;
     99 function ask(k,x,y:longint):longint;
    100 var
    101   mid,ans:longint;
    102 begin
    103    pushdown(k);
    104    if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].min);
    105    mid:=(a[k].l+a[k].r)>>1;ans:=maxlongint;
    106    if x<=mid then ans:=ask(k+k,x,y);
    107    if mid<y then ans:=min(ans,ask(k+k+1,x,y));
    108    exit(ans);
    109 end;
    110 function cal(x,d:longint):longint;
    111 begin
    112    if dep[x]<d then exit(0);
    113    for k:=16 downto 0 do if dep[father[x,k]]>=d then x:=father[x,k];
    114    exit(x);
    115 end;
    116 procedure changee;
    117 begin
    118    while head[x]<>head[y] do
    119       if dep[head[x]]>dep[head[y]] then begin change(1,idx[head[x]],idx[x]);x:=father[head[x],0]; end
    120       else begin change(1,idx[head[y]],idx[y]);y:=father[head[y],0]; end;
    121    if idx[x]<idx[y] then change(1,idx[x],idx[y]) else change(1,idx[y],idx[x]);
    122 end;
    123 function query:longint;
    124 begin
    125    if cap=x then exit(a[1].min);
    126    if cal(cap,dep[x])=x then
    127       begin
    128          t:=cal(cap,dep[x]+1);
    129          if idx[t]+siz[t]>n then exit(ask(1,1,idx[t]-1))
    130          else exit(min(ask(1,1,idx[t]-1),ask(1,idx[t]+siz[t],n)));
    131       end
    132    else exit(ask(1,idx[x],idx[x]+siz[x]-1));
    133 end;
    134 begin
    135    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
    136    readln(n,m);
    137    fillchar(c,sizeof(c),0);cnt:=0;
    138    for i:=1 to n-1 do begin readln(x,y);add(x,y);add(y,x); end;
    139    split;
    140    for i:=1 to n do read(b[idx[i]]);
    141    build(1,1,n);
    142    readln(cap);
    143    for i:=1 to m do
    144       begin
    145         read(op,x);
    146         if op=1 then cap:=x
    147         else if op=2 then begin readln(y,z);changee; end
    148         else if op=3 then writeln(query);
    149       end;
    150    close(input);close(output);
    151 end.
  • 相关阅读:
    满巢尽洒英雄泪
    谋略的原则——经商就是讲谋略的交易
    杨文军(为奥运冠军名字作诗)
    邹市明 (为奥运冠军名字作诗)
    王励勤 (为奥运冠军名字作诗)
    想成功创业:要掌握“三笔钱”和“六三一”原则
    王丽萍(再帮别人名字作诗)
    陆春龙(为奥运冠军名字作诗)
    殷剑 (为奥运冠军名字作诗)
    孟关良(为奥运冠军名字作诗)
  • 原文地址:https://www.cnblogs.com/Currier/p/6666594.html
Copyright © 2011-2022 走看看