jzoj 3583. 【GDOI2014模拟】小A的树
2017-12-25 21:09
218 查看
Description
小A有一棵N个点的树,每个点都有一个小于2^20的非负整数权值。现在小A从树中随机选择一个点x,再随机选择一个点y(x、y可以是同一个点),并对从x到y的路径上所有的点的权值分别做and、or、xor运算,最终会求得三个整数。小A想知道,他求出的三个数的期望值分别是多少。
Input
输入文件包含多组测试数据。
第一行,一个整数T,表示测试数据的组数。
接下来的T节,每节表示一组测试数据,格式如下:
第一行,一个整数N。
第二行,N个整数,其中第i个整数表示第i个点的权值。
接下来的N-1行,每行两个整数a、b,表示树中有一条连接a、b的边。
Output
T行,每行三个实数,结果保留3位小数,其中第i行的三个实数表示由第i组测试数据求得的三个期望值(按照and、or、xor的顺序)。
Sample Input
1
4
1 2 3 4
1 2
2 3
2 4
Sample Output
0.875 4.250 3.375
Data Constraint
对于20%的数据,1<=N<=1000;
对于另外20%的数据,N个点构成一条链;
对于全部的数据,1<=N<=100000,1<=T<=5。
分析:
对于每一种运算,可以把每一位独立出来,给每一位生成一棵树,每个点的权值就是0或1,如果x到y的路径的运算结果为1,则该路径在该位有贡献。那么这棵树的贡献就是,part_sum*(2^k)/(n*n),k就是第k位。我们可以用树形dp求。设f[x,0/1],g[x,0/1],h[x,0/1]表示and,or,xor运算,从x子树内任意一点到x的路径最后结果为0/1的路径数,显然经过x的路径数就是两个不同儿子的状态相乘(这个状态自己推,是真的烦)。
注意爆栈。
代码:
小A有一棵N个点的树,每个点都有一个小于2^20的非负整数权值。现在小A从树中随机选择一个点x,再随机选择一个点y(x、y可以是同一个点),并对从x到y的路径上所有的点的权值分别做and、or、xor运算,最终会求得三个整数。小A想知道,他求出的三个数的期望值分别是多少。
Input
输入文件包含多组测试数据。
第一行,一个整数T,表示测试数据的组数。
接下来的T节,每节表示一组测试数据,格式如下:
第一行,一个整数N。
第二行,N个整数,其中第i个整数表示第i个点的权值。
接下来的N-1行,每行两个整数a、b,表示树中有一条连接a、b的边。
Output
T行,每行三个实数,结果保留3位小数,其中第i行的三个实数表示由第i组测试数据求得的三个期望值(按照and、or、xor的顺序)。
Sample Input
1
4
1 2 3 4
1 2
2 3
2 4
Sample Output
0.875 4.250 3.375
Data Constraint
对于20%的数据,1<=N<=1000;
对于另外20%的数据,N个点构成一条链;
对于全部的数据,1<=N<=100000,1<=T<=5。
分析:
对于每一种运算,可以把每一位独立出来,给每一位生成一棵树,每个点的权值就是0或1,如果x到y的路径的运算结果为1,则该路径在该位有贡献。那么这棵树的贡献就是,part_sum*(2^k)/(n*n),k就是第k位。我们可以用树形dp求。设f[x,0/1],g[x,0/1],h[x,0/1]表示and,or,xor运算,从x子树内任意一点到x的路径最后结果为0/1的路径数,显然经过x的路径数就是两个不同儿子的状态相乘(这个状态自己推,是真的烦)。
注意爆栈。
代码:
const maxn=200001; maxv=20; type node=record y,next:longint; end; var f,g,h:array [1..maxn,0..1] of int64; a:array [1..maxn,1..40] of integer; ls:array [1..maxn] of longint; sf,sg,sh:array [1..maxn,0..1] of int64; adge:array [1..maxn*2] of node; v:array [1..maxn] of longint; t,n,i,m:longint; ef,eg,eh,c:extended; sumf,sumg,sumh:extended; procedure add(x,y:longint); begin inc(m); adge[m].y:=y; adge[m].next:=ls[x]; ls[x]:=m; end; procedure dfs(x:longint;dep:longint); var t,i:longint; begin f[x,0]:=0; f[x,1]:=0; g[x,0]:=0; g[x,1]:=0; h[x,0]:=0; h[x,1]:=0; sf[x,0]:=0; sh[x,0]:=0; sg[x,0]:=0; sf[x,1]:=0; sh[x,1]:=0; sg[x,1]:=0; f[x,a[x,dep]]:=1; g[x,a[x,dep]]:=1; h[x,a[x,dep]]:=1; t:=ls[x]; while t>0 do begin with adge[t] do begin if v[y]=dep-1 then begin v[y]:=v[y]+1; dfs(y,dep); if a[x,dep]=0 then begin f[x,0]:=f[x,0]+f[y,0]; f[x,1]:=f[x,1]+f[y,1]; g[x,0]:=g[x,0]+g[y,1]+g[y,0]; h[x,0]:=h[x,0]+h[y,0]; h[x,1]:=h[x,1]+h[y,1]; ef:=ef+sf[x,0]*f[y,1]+sf[x,1]*f[y,0]; eh:=eh+sh[x,1]*h[y,0]+sh[x,0]*h[y,1]+sh[x,1]*h[y,1]; end else begin f[x,0]:=f[x,0]+f[y,1]; f[x,1]:=f[x,1]+f[y,0]; g[x,0]:=g[x,0]+g[y,0]; g[x,1]:=g[x,1]+g[y,1]; h[x,1]:=h[x,1]+h[y,0]+h[y,1]; ef:=ef+sf[x,0]*f[y,0]+sf[x,1]*f[y,1]; eg:=eg+sg[x,1]*g[y,1]; eh:=eh+(sh[x,0]+sh[x,1])*(h[y,0]+h[y,1]); end; sf[x,0]:=sf[x,0]+f[y,0]; sf[x,1]:=sf[x,1]+f[y,1]; sg[x,0]:=sg[x,0]+g[y,0]; sg[x,1]:=sg[x,1]+g[y,1]; sh[x,0]:=sh[x,0]+h[y,0]; sh[x,1]:=sh[x,1]+h[y,1]; end; t:=next; end; end; if a[x,dep]=0 then begin ef:=ef+sf[x,1]; eh:=eh+sh[x,1]; end else begin ef:=ef+sf[x,0]+0.5; eg:=eg+sg[x,1]+0.5; eh:=eh+sh[x,0]+sh[x,1]+0.5; end; end; procedure main; var i,x,k,y,j:longint; pow:extended; begin readln(n); m:=0; for i:=1 to n do begin read(x); k:=0; while x>0 do begin inc(k); a[i,k]:=x and 1; x:=x shr 1; end; for j:=k+1 to 20 do a[i,j]:=0; ls[i]:=0; v[i]:=0; end; for i:=1 to n-1 do begin readln(x,y); add(x,y); add(y,x); end; sumf:=0; sumg:=0; sumh:=0; pow:=1; for i:=1 to 20 do begin ef:=0; eh:=0; eg:=0; v[1]:=i; dfs(1,i); sumf:=sumf+pow*ef/n/n*2; sumh:=sumh+pow*eh/n/n*2; sumg:=sumg+pow*eg/n/n*2; pow:=pow*2; end; writeln(sumg:0:3,' ',sumh:0:3,' ',sumf:0:3); end; begin readln(t); for i:=1 to t do main; end.
相关文章推荐
- [JZOJ3397]【GDOI2014模拟】雨天的尾巴
- [BZOJ3754][JZOJ3410]【GDOI2014模拟】Tree
- JZOJ.3400【GDOI2014模拟】旅行 解题报告
- [JZOJ3431]【GDOI2014模拟】网格
- [jzoj]3432. 【GDOI2014模拟】服务器(斜率优化或单调队列)
- JZOJ.3431【GDOI2014模拟】网格 解题报告
- JZOJ 3432. 【GDOI2014模拟】服务器
- [JZOJ3401]【GDOI2014模拟】Pty爬山
- jzoj. 3432. 【GDOI2014模拟】服务器
- [JZOJ 3794]. 【NOIP2014模拟8.20】高级打字机
- 【JZOJ5233】【GDOI模拟8.5】概率博弈
- 【jzoj5086】【GDOI2017第四轮模拟day1】【数列】【搜索】
- {题解}[jzoj5051]【GDOI2017模拟一试4.11】平行宇宙
- jzoj5051 【GDOI2017模拟一试4.11】平行宇宙 [贪心,并查集]
- 【GDOI2014模拟】服务器
- 【jzoj5219】【GDOI2018模拟7.10】【B】【动态规划】
- [jzoj]3889. 【NOIP2014模拟10.25B组】序列问题(DP的各种方法+细节+详细分析)
- JZOJ5365. 【GDOI2018模拟9.14】通信 线段树+重链剖分
- 【JZOJ5229】【GDOI2018模拟7.14】小奇的糖果
- 【JZOJ3736】【NOI2014模拟7.11】数学题(math)