jzoj. 3519. 【NOIP2013模拟11.6A组】灵能矩阵(pylon)
来源:互联网 发布:单纯和傻的区别 知乎 编辑:程序博客网 时间:2024/06/05 06:10
Description
Protoss 的灵能矩阵由若干个节点所构成。它们构成了一棵有根树,树根为1 号节点。定义没有子节点的节点为叶节点。叶节点内储存着一定量的能量,而非叶节点的能量为它子树中所有叶节点的能量之和。
如果一个节点的每一个子节点的能量都相同,那么这个节点就是能量平衡的。如果矩阵内每一个节点都能量平衡,则这个矩阵是能量平衡的。
被你所接管的这个灵能矩阵,似乎在长期的废弃之后已经无法保持的能量的平衡。为了重新让矩阵平衡,你可以通过将叶节点储存的能量散逸到太空中。你不可以使一个叶节点储存的能量为负数。
你希望求出最少散逸多少能量到太空中就能使灵能矩阵的能量平衡。
Input
第一行包含一个整数n,表示节点的数量。
接下来一行,包含A1,A2…An 这n 个非负整数,表示每个节点自身储存的能量。保证储存能量的节点都是叶节点。
接下来n -1 行,每行包含两个数字Si, Ti,描述一条从Si 号节点到Ti 号节点的边。
Output
第一行包含一个整数,表示最少要散逸多少单位的能量才能使灵能矩阵的能量平衡。
Sample Input
6
0 0 12 13 5 6
1 2
1 3
1 4
2 5
2 6
Sample Output
6
Data Constraint
对于15% 的数据,1<= n <= 10。
对于30% 的数据,对于边Si, Ti,Si + 1 ̸= Ti 的边数不超过3 条。
对于50% 的数据,1<= n <= 1000。
对于100% 的数据,1 <= n <= 100000,1 <= Ai <= 2^30。
分析:先说一句,每个叶子节点最后的值一定是整数。我们考虑每个叶子节点都是1,往上跑,如果遇到有儿子不相等的情况,显然要把他们变为最小公倍数。
如
/ \ / \ 2 3 / \ / | \ 1 1 1 1 1
最上面是什么呢??我们可以把下面的2,3的子树全部乘3和2,使他们变为最小公倍数,这时
12 / \ / \ 6 6 / \ / | \ 3 3 2 2 2
这时,左右相等了,最上面的根显然是12。所以对于一个节点i,他的值为
f[i]=lcm(f[i.son1],f[i.son2]……f[i.sonx])*x {x为i儿子数,此时的儿子是没有变为公倍数的,就是2,3那个。}。这时,下面的儿子显然也没有变。所以树应该是这样的,满足上面的式子:
12 / \ / \ 2 3 / \ / | \ 1 1 1 1 1
我们可以用上面的方法自下而上求出f[i],再自上而下更新f[i],使树变为状态2,就是第二个图,因为每次把子树都进行乘法,显然会超时。
这时
f[i.son]=f[i]/f[i].x {f[i].x为i的儿子数}
这时若最上面的数为12x,则叶子节点值就为{3x,3x,2x,2x,2x},如果叶子节点集合为{a1,a2,a3,a4,a5},那么我们可以结合不等式求出x的最小值,因为节点值只能变小,有
3x<=a1
3x<=a2
2x<=a3
2x<=a4
2x<=a5
所以,x<=min(ai/f[i]),因为是整数,要向下取整。对于最小的x,乘于系数(就是f[i]),就是这个点要变成的值,用原来的值减去它,再求和即可。
代码:
type node=record y,next:int64; end;var a,ls:array [1..100001] of int64; f,e:array [1..100001] of int64; v:array [1..100001] of boolean; g:array [1..200001] of node; n,m,ans,x,y,d,min:int64; i,j:longint;function lcm(x,y:int64):int64; var r,s,t:int64;begin s:=x; t:=y; r:=x mod y; while r>0 do begin x:=y; y:=r; r:=x mod y; end; exit(s div y*t);end;procedure dfs(x:int64); var t:int64;begin f[x]:=1; if a[x]<>0 then exit; t:=ls[x]; while t>0 do begin with g[t] do begin if v[y]=false then begin v[y]:=true; dfs(y); inc(e[x]); f[x]:=lcm(f[x],f[y]); end; t:=next; end; end; f[x]:=f[x]*e[x];end;procedure dfsq(x:longint); var t:int64;begin if a[x]<>0 then exit; t:=ls[x]; while t>0 do begin with g[t] do begin if v[y]=false then begin v[y]:=true; f[y]:=f[x] div e[x]; dfsq(y); end; t:=next; end; end;end;begin assign(input,'pylon.in'); assign(output,'pylon.out'); reset(input); rewrite(output); readln(n); for i:=1 to n do read(a[i]); for i:=1 to n-1 do begin readln(x,y); g[i].y:=y; g[i].next:=ls[x]; ls[x]:=i; g[i+n].y:=x; g[i+n].next:=ls[y]; ls[y]:=i+n; end; v[1]:=true; dfs(1); fillchar(v,sizeof(v),false); v[1]:=true; dfsq(1); min:=maxlongint; for i:=1 to n do if (a[i] div f[i]<min) and (a[i]<>0) then min:=a[i] div f[i]; for i:=1 to n do if a[i]<>0 then ans:=ans+a[i]-min*f[i]; writeln(ans); close(input); close(output);end.
- jzoj. 3519. 【NOIP2013模拟11.6A组】灵能矩阵(pylon)
- 【NOIP2013模拟11.6A组】灵能矩阵(pylon)
- jzoj. 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)
- JZOJ 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)
- JZOJ 3506. 【NOIP2013模拟11.4A组】善良的精灵
- JZOJ 3506. 【NOIP2013模拟11.4A组】善良的精灵
- JZOJ 3526. 【NOIP2013模拟11.7A组】不等式(solve)
- jzoj. 3526. 【NOIP2013模拟11.7A组】不等式(solve)
- jzoj. 3505. 【NOIP2013模拟11.4A组】积木(brick)
- JZOJ 3505. 【NOIP2013模拟11.4A组】积木(brick)
- jzoj. 3523. 【NOIP2013模拟11.7A组】JIH的玩偶(tree)
- [jzoj]3505. 【NOIP2013模拟11.4A组】积木(brick) (排列组合vsDP)
- [jzoj]3526. 【NOIP2013模拟11.7A组】不等式(solve)(类欧几里得)
- JZOJ-senior-3502. 【NOIP2013模拟11.4B组】方格游戏
- jzoj 3520. 【NOIP2013模拟11.7B组】原根(math)
- jzoj. 3522. 【NOIP2013模拟11.7B组】迷宫花园(maze)
- jzoj. 3521. 【NOIP2013模拟11.7B组】道路覆盖(cover)
- [jzoj]3511. 【NOIP2013模拟11.5A组】cza的蛋糕(cake)(DP嵌套dfs【快】或DP【慢】)
- 批量导入数据到MySQL数据库
- 神经网络——深度学习
- 【bzoj1699】[Usaco2007 Jan][Balanced Lineup排队]
- LinkedHashMap 实现“最近最少使用”的原则,PriorityQueue优先级
- 2017-07-08【NOIP-普及组】模拟赛C组-count-题解
- jzoj. 3519. 【NOIP2013模拟11.6A组】灵能矩阵(pylon)
- 2017-07-08【NOIP-普及组】模拟赛C组-sort-题解
- TCP的三次握手和四次挥手详解
- 2017-07-08【NOIP-普及组】模拟赛C组-sum-题解
- 2017-07-08【NOIP提高组】模拟赛B组-连通块(connect)-题解
- ToBase64String方法
- 理解Linux系统负荷
- 2017-07-08【NOIP提高组】模拟赛B组-山峰(summits)-题解
- suse系统解决ssh登录慢的办法