好强的题。

  方案不好算,改成算概率,注意因为是模意义下的概率所以直接乘法逆元就好不要傻傻地开double。

  设$f[i][d][0]$为第i个节点离d层的球球走到第i个点时第i个点没有球的概率, $f[i][d][1]$为有1个球的概率, $f[i][d][2]$为有2个球及以上的概率。

  我们可以把$f[i]$看成一个队列, 然后从儿子转移的时候, 就是把儿子的队列一个一个合并起来,最后在队列头加上一个$f[i][0]$, 并且把队列里的所有$f[i][0$~$d][2]$加上$f[i][0$~$d][0]$,并且$f[i][0$~$d][2]$变成0就好了。

  合并的时候转移为:

  $f[i][d][0]=f[i][d][0]*f[j][d][0]$

  $f[i][d][1]=f[i][d][1]*f[j][d][0]+f[i][d][0]*f[j][d][1]$

  $f[i][d][2]=f[i][d][0]*f[j][d][2]+f[i][d][1]*f[j][d][2]+f[i][d][1]*f[j][d][1]+f[i][d][2]*f[j][d][2]+f[i][d][2]*f[j][d][1]+f[i][d][2]*f[j][d][0]$

  复杂度为O(N),因为每层元素只加1,交集最多为N。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#define ll long long
#define MOD(x) ((x)>=mod?(x)-mod:(x))
using namespace std;
const int maxn=, mod=1e9+;
struct tjm{int too, pre;}e[maxn<<];
struct poi{int f[];};
int n, x, ans, tot, tott;
int last[maxn], root[maxn];
vector<poi>q[maxn];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void add(int x, int y){e[++tot]=(tjm){y, last[x]}; last[x]=tot;}
inline int merge(int x, int y)
{
if(q[x].size()<q[y].size()) swap(x, y);
int nx=q[x].size()-, ny=q[y].size()-;
for(int i=;i<=ny;i++)
{
int sum0=, sum1=, sum2=;
sum0=1ll*q[x][nx-i].f[]*q[y][ny-i].f[]%mod;
sum1=(1ll*q[x][nx-i].f[]*q[y][ny-i].f[]+1ll*q[x][nx-i].f[]*q[y][ny-i].f[])%mod;
for(int j=;j<;j++)
for(int k=;j+k>=;k--)
sum2=(1ll*sum2+1ll*q[x][nx-i].f[j]*q[y][ny-i].f[k])%mod;
q[x][nx-i].f[]=sum0; q[x][nx-i].f[]=sum1; q[x][nx-i].f[]=sum2;
}
q[y].clear(); return x;
}
void dfs(int x, int fa)
{
if(!last[x]) root[x]=++tott; int dep=;
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa)
{
dfs(too, x);
if(!root[x]) root[x]=root[too];
else dep=max(dep, (int)min(q[root[x]].size(), q[root[too]].size())), root[x]=merge(root[x], root[too]);
}
int nx=q[root[x]].size()-;
for(int i=;i<dep;i++)
q[root[x]][nx-i].f[]=MOD(q[root[x]][nx-i].f[]+q[root[x]][nx-i].f[]), q[root[x]][nx-i].f[]=;
poi tmp; tmp.f[]=tmp.f[]=(mod+)>>; tmp.f[]=; q[root[x]].push_back(tmp);
}
inline int power(int a, int b)
{
int ans=;
for(;b;b>>=, a=1ll*a*a%mod)
if(b&) ans=1ll*ans*a%mod;
return ans;
}
int main()
{
read(n);
for(int i=;i<=n;i++) read(x), add(x, i);
dfs(, -);
for(int i=;i<q[root[]].size();i++) ans=MOD(ans+q[root[]][i].f[]);
printf("%lld\n", 1ll*ans*power(, n+)%mod);
}

AtCoder Regular Contest 086 E - Smuggling Marbles(树形迭屁)的更多相关文章

  1. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  2. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  3. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  4. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

  5. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

  6. AtCoder Regular Contest 095

    AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...

  7. AtCoder Regular Contest 102

    AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...

  8. AtCoder Regular Contest 096

    AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...

  9. AtCoder Regular Contest 097

    AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...

随机推荐

  1. Dsniff简介

    原文发表于:2010-09-25 转载至cu于:2012-07-21 前两天因为看局域网安全的视频中介绍dsniff,也想自己安装下来看看效果.简单的使用没什么难的(高级使用就需要研究文档了),但是安 ...

  2. IO多路复用(二) -- select、poll、epoll实现TCP反射程序

    接着上文IO多路复用(一)-- Select.Poll.Epoll,接下来将演示一个TCP回射程序,源代码来自于该博文https://www.cnblogs.com/Anker/p/3258674.h ...

  3. Thymeleaf教程【转】

    作者:不做浮躁的人 转自:http://www.blogjava.net/bjwulin/archive/2013/02/07/395234.html PS:其他推荐教程地址 http://blog. ...

  4. 作业要求20181113-4 Beta阶段第1周/共2周 Scrum立会报告+燃尽图 02

    作业要求:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2384 版本控制:[https://git.coding.net/lglr201 ...

  5. Alpha发布_文案+美工

    团队名称:探路者 1蔺依铭:http://www.cnblogs.com/linym762/ 2张恩聚:http://www.cnblogs.com/zej87/ 3米赫:http://www.cnb ...

  6. HDU 4055 Number String dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4055 Number String Time Limit: 10000/5000 MS (Java/O ...

  7. HDU 5269 ZYB loves Xor I Trie树

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5269 bc:http://bestcoder.hdu.edu.cn/contests/con ...

  8. 如何解决Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]

    APP改版测试后准备Archive发布时,结果居然出现题目中的错误提示.查了一下,如果archive的时候没有选[iOS](http://lib.csdn.net/base/ios)  Devices ...

  9. TCP系列41—拥塞控制—4、Linux中的慢启动和拥塞避免(一)

    一.Linux中的慢启动和拥塞避免 Linux中采用了Google论文的建议把IW初始化成了10了.在linux中一般有三种场景会触发慢启动过程 1.连接初始建立发送数据的时候,此时cwnd初始化为1 ...

  10. 七周七语言之用Io编写领域特定语言

    如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/05/sevenlang-io/. Io 语言 ...