好强的题。

  方案不好算,改成算概率,注意因为是模意义下的概率所以直接乘法逆元就好不要傻傻地开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. request,logging,ConfigParser——接口框架

    做一个将参数和用例分开放置,并且输出log的接口测试框架 我的框架如下所示 Log文件用来设置log输出文件,需要时可以在用例内调用输出,config用来填写一切需要的参数信息,jiekou_post ...

  2. 运输层(TCP/UDP)详解

    TCP和UDP的区别: tcp是面向连接的可靠的传输协议 udp是非连接的不可靠的传输协议 TCP组成 可以看到虽然tcp是面向字节流的,但是其传输的基本单位还是报文(tcp首部和数据,ip报文和ud ...

  3. Bellman-ford 模板

    #include<bits/stdc++.h> const int inf=0x3f3f3f3f; ; struct edge{ int u,v;//两个点 int w; //权值 Edg ...

  4. 【转载】windows安装python2.7后的注册表问题

    原文出自:https://www.cnblogs.com/tlz888/p/6879227.html [提要]win平台上,python2.7官网的安装包在安装后不会添加环境变量且不会把安装信息写入注 ...

  5. js 插件 issue

    1 iscroll 5 和 lazyload 同时使用  转自 yinjie //lazyload var $scrollEle = $("#wrapper") $("i ...

  6. P4语法(3)Table,Action

    Table table是p4的匹配——动作表,定义了匹配字段(key).动作(action)和一些其他相关属性. 其处理数据包的流程: Key construction.建立其匹配字段 Key loo ...

  7. Alpha 冲刺(6/10)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 测试服务器并行能力 学习MSI.CUDA ...

  8. 博弈---尼姆博奕(Nimm Game)(重点)

    尼姆博奕(Nimm Game):有三堆各若干个物品,两个人轮流从某一堆取任意多的 物品,规定每次至少取一个,多者不限,最后取光者得胜. 这种情况最有意思,它与二进制有密切关系,我们用(a,b,c)表示 ...

  9. 阅读笔记《我是一只IT小小鸟》

    我是一只IT小小鸟 我们在尝试新的事物的时候,总是会遇到各种各样的困难,不同的人会在碰壁不同的次数之后退出.用程序员喜欢的话来说就是,我们都在for循环,区别在于你是什么情况下break;的.有的人退 ...

  10. Rsyslog的模板template详解

    一. Template功能 根据用户需求指定任意格式 动态生成文件名 每个输出都使用了一些模板,包括针对文件的,针对用户消息等 备注: 旧版本:$template 新版本:template() V6之 ...