bzoj4719[Noip2016]天天爱跑步
Posted Currier
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4719[Noip2016]天天爱跑步相关的知识,希望对你有一定的参考价值。
Description
Input
Output
输出1行N 个整数,第个整数表示结点的观察员可以观察到多少人。
Sample Input
2 3
1 2
1 4
4 5
4 6
0 2 5 1 2 3
1 5
1 3
2 6
Sample Output
HINT
5 3
1 2
2 3
2 4
1 5
0 1 0 3 0
3 1
1 4
5 5
1 2 1 0 1
【子任务】
每个测试点的数据规模及特点如下表所示。 提示: 数据范围的个位上的数字可以帮助判断是哪一种数据类型。
【提示】
如果你的程序需要用到较大的栈空问 (这通常意味着需要较深层数的递归), 请务必仔细阅读选手日录下的文本当rumung:/stact.p″, 以了解在最终评测时栈空问的限制与在当前工作环境下调整栈空问限制的方法。
在最终评测时,调用栈占用的空间大小不会有单独的限制,但在我们的工作
环境中默认会有 8 MB 的限制。 这可能会引起函数调用层数较多时, 程序发生
栈溢出崩溃。
我们可以使用一些方法修改调用栈的大小限制。 例如, 在终端中输入下列命
令 ulimit -s 1048576
此命令的意义是,将调用栈的大小限制修改为 1 GB。
例如,在选手目录建立如下 sample.cpp 或 sample.pas
将上述源代码编译为可执行文件 sample 后,可以在终端中运行如下命令运
行该程序
./sample
如果在没有使用命令“ ulimit -s 1048576”的情况下运行该程序, sample
会因为栈溢出而崩溃; 如果使用了上述命令后运行该程序,该程序则不会崩溃。
特别地, 当你打开多个终端时, 它们并不会共享该命令, 你需要分别对它们
运行该命令。
请注意, 调用栈占用的空间会计入总空间占用中, 和程序其他部分占用的内
存共同受到内存限制。
考场上我做了暴力和s=1的特殊情况。
本蒟蒻表示看了半天题解才懂。
正解:
对于每一条路径,拆成一条向上的链和一条向下的链,在向上的链中,需满足d[s]-d[i]=w[i],即d[s]=d[i]+w[i],问题转化为,在树上将s到lca的路径标上d[s],最后ans[i]就等于在i点上等于d[i]+w[i]的标记的个数。但直接标记路径上所有的点太慢,我们可以在s点打上+1的标记,lca点打上-1的标记,然后dfs做求子树和,为避免将其它子树的和计入ans,只要记录进入这个点时的cnt[d[i]+w[i]],访问完这个点后用新的cnt[d[i]+w[i]]减去进来的就可以了。一些实现上的细节见代码。
蒟蒻表示不会tarjanLCA所以写了个倍增lca。
1 program running(input,output); 2 type 3 etype=record 4 t,next:longint; 5 end; 6 pointer=^nodetype; 7 nodetype=record 8 x:longint; 9 next:pointer; 10 end; 11 var 12 e:array[0..600060]of etype; 13 u,v,d,c,lca,q,w,ans:array[0..300030]of longint; 14 vis:array[0..300030]of boolean; 15 cnt:array[-600060..600060]of longint; 16 father:array[0..300030,0..20]of longint; 17 a,b:array[0..300030]of pointer; 18 p:pointer; 19 n,m,i,j,k,x,y,tot,h,t:longint; 20 procedure add(x,y:longint); 21 begin 22 inc(tot);e[tot].t:=y;e[tot].next:=c[x];c[x]:=tot; 23 end; 24 function query(x,y:longint):longint; 25 begin 26 if d[x]<d[y] then begin t:=x;x:=y;y:=t; end; 27 j:=k;while d[x]>d[y] do begin if d[father[x,j]]>=d[y] then x:=father[x,j];dec(j); end; 28 if x=y then exit(x); 29 j:=k;while j>=0 do begin if father[x,j]<>father[y,j] then begin x:=father[x,j];y:=father[y,j]; end;dec(j); end; 30 exit(father[x,0]); 31 end; 32 procedure prepare; 33 begin 34 fillchar(d,sizeof(d),0); 35 h:=0;t:=1;q[1]:=1;d[1]:=1;father[1,0]:=0; 36 while h<t do 37 begin 38 inc(h); 39 i:=c[q[h]]; 40 while i<>0 do 41 begin 42 if d[e[i].t]=0 then 43 begin 44 d[e[i].t]:=d[q[h]]+1;father[e[i].t,0]:=q[h]; 45 inc(t);q[t]:=e[i].t; 46 end; 47 i:=e[i].next; 48 end; 49 end; 50 k:=1; 51 for i:=1 to 20 do begin if k+k>=d[q[n]] then break;k:=k+k; end; 52 k:=i; 53 for j:=1 to k do 54 for i:=1 to n do father[i,j]:=father[father[i,j-1],j-1]; 55 for i:=1 to m do lca[i]:=query(u[i],v[i]); 56 end; 57 procedure ins(x,y:longint); 58 begin 59 new(p);p^.x:=y;p^.next:=a[x];a[x]:=p; 60 end; 61 procedure del(x,y:longint); 62 begin 63 new(p);p^.x:=y;p^.next:=b[x];b[x]:=p; 64 end; 65 procedure dfs1(k:longint); 66 var 67 i,j:longint; 68 begin 69 vis[k]:=true; 70 j:=cnt[w[k]+d[k]]; 71 i:=c[k]; 72 while i<>0 do 73 begin 74 if not vis[e[i].t] then dfs1(e[i].t); 75 i:=e[i].next; 76 end; 77 p:=a[k];while p<>nil do begin inc(cnt[p^.x]);p:=p^.next; end; 78 ans[k]:=cnt[w[k]+d[k]]-j; 79 p:=b[k];while p<>nil do begin dec(cnt[p^.x]);p:=p^.next; end; 80 end; 81 procedure dfs2(k:longint); 82 var 83 i,j:longint; 84 begin 85 vis[k]:=true; 86 j:=cnt[w[k]-d[k]]; 87 i:=c[k]; 88 while i<>0 do 89 begin 90 if not vis[e[i].t] then dfs2(e[i].t); 91 i:=e[i].next; 92 end; 93 p:=a[k];while p<>nil do begin inc(cnt[p^.x]);p:=p^.next; end; 94 p:=b[k];while p<>nil do begin dec(cnt[p^.x]);p:=p^.next; end; 95 ans[k]:=ans[k]+cnt[w[k]-d[k]]-j; 96 end; 97 begin 98 assign(input,‘running.in‘);assign(output,‘running.out‘);reset(input);rewrite(output); 99 readln(n,m); 100 tot:=0;fillchar(c,sizeof(c),0); 101 for i:=2 to n do begin readln(x,y);add(x,y);add(y,x); end; 102 for i:=1 to n do read(w[i]); 103 for i:=1 to m do readln(u[i],v[i]); 104 prepare; 105 for i:=1 to n do begin a[i]:=nil;b[i]:=nil; end; 106 for i:=1 to m do begin ins(u[i],d[u[i]]);del(lca[i],d[u[i]]); end; 107 fillchar(cnt,sizeof(cnt),0); 108 fillchar(vis,sizeof(vis),false); 109 dfs1(1); 110 for i:=1 to n do begin a[i]:=nil;b[i]:=nil; end; 111 for i:=1 to m do begin t:=d[u[i]]-d[lca[i]]-d[lca[i]];ins(v[i],t);del(lca[i],t); end; 112 fillchar(cnt,sizeof(cnt),0); 113 fillchar(vis,sizeof(vis),false); 114 dfs2(1); 115 write(ans[1]);for i:=2 to n do write(‘ ‘,ans[i]); 116 close(input);close(output); 117 end.
以上是关于bzoj4719[Noip2016]天天爱跑步的主要内容,如果未能解决你的问题,请参考以下文章
bzoj4719: [Noip2016]天天爱跑步 树上差分