AtCoder Regular Contest 086 E - Smuggling Marbles(树形迭屁)
好强的题。
方案不好算,改成算概率,注意因为是模意义下的概率所以直接乘法逆元就好不要傻傻地开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(树形迭屁)的更多相关文章
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
- AtCoder Regular Contest 094
AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...
- AtCoder Regular Contest 095
AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
- AtCoder Regular Contest 096
AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...
- AtCoder Regular Contest 097
AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...
随机推荐
- 移动端车牌识别/车牌OCR识别
周末,小编约了朋友商场shopping. 开车进地下车库时,“滴”的一声,完成车牌录入:开车离开时,扫描二维码,输入车牌,完成停车收费.小编不禁感叹科技改变生活,人工智能给生活带来的便利. 车牌自动识 ...
- spark读取外部配置文件的方法
spark读取外部配置文件的方法 spark-submit --files /tmp/fileName /tmp/test.jar 使用spark提交时使用--files参数,spark会将将本地的 ...
- 【ZABBIX】ZABBIX3.2升级3.4
小贴士 1.停止zabbix服务 service zabbix_server stop service zabbix_agentd stop /usr/local/zabbix/sbin/zabbix ...
- NO.2:自学python之路------变量类型、列表、字典
引言 本周初步认识了库,并学习了Python中各种类型的变量和常用操作.并完成了较为完善的用户与商家购物界面设计. 正文 模块: Python有标准库和第三方库.第三方库需要安装才能使用.大量的库可以 ...
- nginx upstream 名称下划线问题
原始配置: user nobody;worker_processes 1; #pid logs/nginx.pid; worker_connections 1024;} http ...
- JavaScript之函数柯里化
什么是柯里化(currying)? 维基百科中的解释是:柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术.意思就是当函 ...
- linshi12
#include<iostream> using namespace std; int main(){ int a[50]; a[1]=5; int i; for(i=2;;i++){ a ...
- HDU 4055 Number String dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4055 Number String Time Limit: 10000/5000 MS (Java/O ...
- Codeforces Round #272 (Div. 2) E. Dreamoon and Strings dp
题目链接: http://www.codeforces.com/contest/476/problem/E E. Dreamoon and Strings time limit per test 1 ...
- C#高级编程 (第六版) 学习 第七章:委托和事件
第七章 委托和事件 回调(callback)函数是Windows编程的一个重要方面,实际上是方法调用的指针,也称为函数指针. .Net以委托的形式实现了函数指针的概念,.Net的委托是类型安全的. 委 ...