JZOJ 5444. 【NOIP2017提高A组冲刺11.2】救赎
来源:互联网 发布:淘宝otc货到付款可信吗 编辑:程序博客网 时间:2024/06/05 11:38
Description
“是的。”我回答,“我不会忘记你。在森林里我会一点点记起往日的世界。要记起的大概很多很多:各种人、各种场所、各种光、各种歌曲……”
——村上春树《世界尽头与冷酷仙境》
在没有心存在的世界尽头,音乐能够使小镇居民消散的心重新聚拢成形。作为镇子里唯一一个还残留着些许音乐记忆的人,我逐渐记起了往昔点滴……
记忆中有一棵无根树,有n个节点。
对于一棵有根树的每一个非叶子节点,我们都等概率选中其一个儿子节点作为偏好儿子。对于一条从父亲指向儿子的树边(u,v),如果v是u的偏好儿子,则称这条边为重边,否则为轻边。
我们定义一棵有根树的权值为其每一个节点到根路径上的轻边条数的和的期望值。
请对无根树每一个节点输出其为根的有根树的权值。答案模998244353。
Input
文件第一行是一个正整数n。
接下来n-1行,每行两个正整数(x,y)表示一条树边。
Output
输出文件共n行,每一行一个整数表示答案。
Sample Input
5
1 2
1 3
3 4
3 5
Sample Output
3
1
665496238
499122178
499122178
Data Constraint
对于10%的数据,保证n<=10。
对于30%的数据,保证n<=2000。
对于100%的数据,保证n<=10^5。
Solution
利用期望的线性既可以得出对于一个有根树的答案是,复杂度
O(N2) :∑i=1n(sizei−1)∗(soni−1)soni 但是可以发现换一次根许多点的贡献都不变,
那么我们先跑出以 1 为根的答案,每次
O(1) 换根后,更改相邻的边的贡献即可。而且我们可以
O(N) 预处理出1−N 的逆元,详细方法和证明见下面链接:O(N) 求 1~N 逆元方法及证明
这样时间复杂度就成了大常数的
O(N) 。
Code
#include<cstdio>using namespace std;typedef long long LL;const int N=1e5+1,mo=998244353;int n,tot;int first[N],next[N<<1],en[N<<1];int fa[N],size[N],son[N];LL ans[N],inv[N];inline int read(){ int X=0,w=1; char ch=0; while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();} while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar(); return X*w;}inline void write(int x){ if(x>9) write(x/10); putchar(x%10+'0');}inline void insert(int x,int y){ next[++tot]=first[x]; first[x]=tot; en[tot]=y;}inline void dfs(int x){ size[x]=1,son[x]=0; for(int i=first[x];i;i=next[i]) if(en[i]!=fa[x]) { fa[en[i]]=x; son[x]++; dfs(en[i]); size[x]+=size[en[i]]; }}inline void find(int x){ if(fa[x]) ans[1]=(ans[1]+(son[fa[x]]-1)*inv[son[fa[x]]]%mo*size[x])%mo; for(int i=first[x];i;i=next[i]) if(en[i]!=fa[x]) find(en[i]);}inline void work(int x){ int y=fa[x];LL sum=0; if(son[y]) sum=(sum+mo-(n-1)*(son[y]-1)*inv[son[y]]%mo)%mo; if(son[x]) sum=(sum+mo-(size[x]-1)*(son[x]-1)%mo*inv[son[x]]%mo)%mo; fa[y]=x,fa[x]=0; son[x]++,son[y]--; int z=size[x];size[x]=n,size[y]-=z; if(son[x]) sum=(sum+(n-1)*(son[x]-1)%mo*inv[son[x]]%mo)%mo; if(son[y]) sum=(sum+(size[y]-1)*(son[y]-1)%mo*inv[son[y]]%mo)%mo; ans[x]=(ans[y]+sum)%mo; for(int i=first[x];i;i=next[i]) if(en[i]!=y) work(en[i]); fa[x]=y,fa[y]=0; son[x]--,son[y]++; size[x]=z,size[y]=n;}int main(){ n=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); insert(x,y); insert(y,x); } inv[0]=inv[1]=1; for(int i=2;i<=n;i++) inv[i]=(mo-mo/i)*inv[mo%i]%mo; dfs(1),find(1); for(int i=first[1];i;i=next[i]) work(en[i]); for(int i=1;i<=n;i++) write(ans[i]),putchar('\n'); return 0;}
阅读全文
1 0
- JZOJ 5444. 【NOIP2017提高A组冲刺11.2】救赎
- JZOJ 5444. 【NOIP2017提高A组冲刺11.2】救赎
- 【NOIP2017提高A组冲刺11.2】救赎(数学期望)
- Jzoj5444【NOIP2017提高A组冲刺11.2】救赎
- JZOJ5444. 【NOIP2017提高A组冲刺11.2】救赎
- 【JZOJ 5445】【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5443. 【NOIP2017提高A组冲刺11.2】字典序
- jzoj【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5445. 【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5445. 【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5440. 【NOIP2017提高A组冲刺11.1】背包
- JZOJ 5441. 【NOIP2017提高A组冲刺11.1】序列
- 【JZOJ 5442】【NOIP2017提高A组冲刺11.1】荒诞
- 【JZOJ 5441】【NOIP2017提高A组冲刺11.1】序列
- JZOJ 5442. 【NOIP2017提高A组冲刺11.1】荒诞
- 【JZOJ 5451】【NOIP2017提高A组冲刺11.4】Genocide
- 【JZOJ 5449】【NOIP2017提高A组冲刺11.4】Pacifist
- 【JZOJ 5452】【NOIP2017提高A组冲刺11.5】轰炸
- 复归
- Python 字符串操作方法大全
- 阿里云服务器ces
- Spring Boot 快速上手(六)集成MongoDB
- 30 个常用 Maven 命令
- JZOJ 5444. 【NOIP2017提高A组冲刺11.2】救赎
- ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
- 用php获取本周,上周,本月,上月,本季度日期的代码
- 有一种策略...
- Java基础总结篇--JavaSE你必须要知道的基础
- Monkey自动化测试
- freemarker 循环list 并取值
- Android 6.0 的权限管理自己简单的封装--(到BaseActivity)
- 开发工具介绍