正题

题目链接:https://ac.nowcoder.com/acm/contest/7745/E


题目大意

给出\(n\)个点的一棵树,每个点有一个选择权重\(a_i\)(有\(\frac{a_i}{\sum_{i=1}^na_i}\)的概率被选择)。

然后有一个序列\(w\)。随机选择两次点(可以相同)若它们之间距离为\(L\),那么困难值为\(w_L\)

求期望困难值。

\(1\leq n\leq 10^5,0\leq w_i\leq 10^8\)


解题思路

设\(p_i\)表示选择\(i\)的概率那么就是求

\[\sum_{i=1}^n\sum_{j=1}^np_ip_jw_{dis(i,j)}
\]

看起来很点分治就上点分治吧

怎么合并两个子树的距离,设\(u_i\)表示子树\(1\)中深度为\(i\)的概率和,\(v_i\)则表示子树\(2\)中的。

那么就有

\[ans=\sum_{i=1}\sum_{j=1}u_iv_iw_{i+j}=\sum_{i=1}w_{i}\sum_{j=1}u_jv_{i-j}
\]

看起来很卷积就上\(\text{NTT}\)吧

做起来比较麻烦,题解告诉我们可以直接计算整个树的然后再分别减去每个子树内的。

时间复杂度\(O(n\log^2 n)\)

这下一雪我半年前考场调了半天长剖+NTT的前耻了


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=4e5+10,P=998244353;
struct node{
ll to,next;
}a[N<<1];
ll n,l,ans,root,num,mx,tot,ls[N],p[N],w[N];
ll r[N],g[N],siz[N],f[N],x[N];
bool v[N];
ll power(ll x,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
void addl(ll x,ll y){
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;return;
}
void NTT(ll *f,ll op){
for(ll i=0;i<l;i++)
if(i<r[i])swap(f[i],f[r[i]]);
for(ll p=2;p<=l;p<<=1){
ll len=p>>1,tmp=power(3,(P-1)/p);
if(op==-1)tmp=power(tmp,P-2);
for(ll k=0;k<l;k+=p){
ll buf=1;
for(ll i=k;i<k+len;i++){
ll tt=buf*f[i+len]%P;
f[i+len]=(f[i]-tt+P)%P;
f[i]=(f[i]+tt)%P;
buf=buf*tmp%P;
}
}
}
if(op==-1){
ll invn=power(l,P-2);
for(ll i=0;i<l;i++)
f[i]=f[i]*invn%P;
}
return;
}
void GetL(ll n){
l=1;while(l<n)l<<=1;
for(ll i=0;i<l;i++)
r[i]=(r[i>>1]>>1)|((i&1)?(l>>1):0);
return;
}
void groot(ll x,ll fa){
siz[x]=1;g[x]=0;
for(ll i=ls[x];i;i=a[i].next){
ll y=a[i].to;
if(y==fa||v[y])continue;
groot(y,x);siz[x]+=siz[y];
g[x]=max(g[x],siz[y]);
}
g[x]=max(g[x],num-siz[x]);
if(g[x]<g[root])root=x;
return;
}
void calc(ll x,ll fa,ll dep){
(f[dep]+=p[x])%=P;
mx=max(mx,dep);
for(ll i=ls[x];i;i=a[i].next){
ll y=a[i].to;
if(y==fa||v[y])continue;
calc(y,x,dep+1);
}
return;
}
void del(){
for(ll i=0;i<=mx;i++)f[i]=0;
mx=0;return;
}
void fuc(ll n,ll z){
GetL(2*n);
for(ll i=0;i<l;i++)x[i]=f[i];
NTT(x,1);
for(ll i=0;i<l;i++)x[i]=x[i]*x[i]%P;
NTT(x,-1);
for(ll i=0;i<l;i++)
(ans+=z*w[i]*x[i]%P)%=P;
return;
}
void solve(ll x){
v[x]=1;ll tal=num;
calc(x,x,0);fuc(mx+1,1);del();
for(ll i=ls[x];i;i=a[i].next){
ll y=a[i].to;
if(v[y])continue;
calc(y,x,1);fuc(mx+1,-1);del();
}
for(ll i=ls[x];i;i=a[i].next){
ll y=a[i].to;
if(v[y])continue;
num=(siz[y]>siz[x])?(tal-siz[x]):siz[y];
root=0;groot(y,x);solve(root);
}
return;
}
signed main()
{
scanf("%lld",&n);ll s=0;
for(ll i=1;i<=n;i++)
scanf("%lld",&p[i]),s+=p[i];
for(ll i=1;i<=n;i++)
p[i]=p[i]*power(s,P-2);
for(ll i=0;i<n;i++)scanf("%lld",&w[i]);
for(ll i=1;i<n;i++){
ll x,y;
scanf("%lld%lld",&x,&y);
addl(x,y);addl(y,x);
}
num=n;g[0]=1e9;
groot(1,1);
solve(1);
printf("%lld\n",(ans+P)%P);
return 0;
}

牛客练习赛71E-神奇的迷宫【点分治,NTT】的更多相关文章

  1. 牛客练习赛22C Bitset

    牛客练习赛22C 一共有 n个数,第 i 个数是 xi  xi 可以取 [li , ri] 中任意的一个值. 设 ,求 S 种类数. 感觉二进制真是一个神奇的东西. #include <iost ...

  2. 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D

    目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...

  3. 牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 逻辑,博弈 B

    牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 https://ac.nowcoder.com/acm/contest/218/B 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...

  4. 牛客练习赛31 D 神器大师泰兹瑞与威穆 STL,模拟 A

    牛客练习赛31 D 神器大师泰兹瑞与威穆 https://ac.nowcoder.com/acm/contest/218/D 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 26214 ...

  5. 最小生成树--牛客练习赛43-C

    牛客练习赛43-C 链接: https://ac.nowcoder.com/acm/contest/548/C 来源:牛客网 题目描述 ​ 立华奏是一个刚刚开始学习 OI 的萌新. 最近,实力强大的 ...

  6. 牛客练习赛28-B(线段树,区间更新)

    牛客练习赛28 - B 传送门 题目 qn姐姐最好了~ ​ qn姐姐给你了一个长度为n的序列还有m次操作让你玩, ​ 1 l r 询问区间[l,r]内的元素和 ​ 2 l r 询问区间[l,r]内的 ...

  7. 牛客练习赛26:D-xor序列(线性基)

    链接:牛客练习赛26:D-xor序列(线性基) 题意:小a有n个数,他提出了一个很有意思的问题:他想知道对于任意的x, y,能否将x与这n个数中的任意多个数异或任意多次后变为y 题解:线性基 #inc ...

  8. [堆+贪心]牛客练习赛40-B

    传送门:牛客练习赛40 题面: 小A手头有 n 份任务,他可以以任意顺序完成这些任务,只有完成当前的任务后,他才能做下一个任务 第 i 个任务需要花费  x_i 的时间,同时完成第 i 个任务的时间不 ...

  9. 牛客练习赛 29 E 位运算?位运算!(线段树)

    题目链接  牛客练习赛29E 对$20$位分别建立线段树.首先$1$和$2$可以合起来搞(左移右移其实是等效的) 用个lazy标记下.转移的时候加个中间变量. $3$和$4$其实就是区间$01$覆盖操 ...

随机推荐

  1. Centos7 出现Welcome to emergency mode!【紧急模式】

    Centos7 出现Welcome to emergency mode![紧急模式] 做mount挂载时,修改了  /etc/fstab 文件,导致Centos7重启时出现如下图所示错误:   输入r ...

  2. JSON.stringify()还可以这么用

    最近做项目的时候遇到一个对象深拷贝的问题,网上看了下发现最为简便的方法是JSON.stringify(),比如你要深拷贝一个对象,可以这么做: var test={ a:"hello&quo ...

  3. flutter中修改键盘状态

    当用户进行表格输入时,为更方便的方便用户操作,我们需要设置键盘状态方便用户点击,如当表格填写完成时,用户可以直接点击键盘下面的"完成"状态完成提交. 实现如下: TextFormF ...

  4. 终于讲清楚了:深入理解Java 应用程序中 final 关键字的各种使用场景

    在 Java 语言众多的关键字中,final 关键字无疑是被提到最多的,也是在面试过程中经常被问到的知识点.今天,老王查找了很多材料,最后终于收集了关于 final 关键字比较全的知识点.首先,fin ...

  5. C#中的几种锁:用户模式锁、内核模式锁、动态计数、监视锁

    参考网址: https://blog.csdn.net/weixin_43989331/article/details/105356008 C#中的几种锁:用户模式锁.内核模式锁.动态计数.监视锁介绍 ...

  6. 从0开始搭建一个IoC容器(C#版)

    网址:https://blog.csdn.net/wangyahua1234/article/details/100619695 目录 1. IoC简介 2. Tiny版IoC的功能 3. Tiny版 ...

  7. Spring整合Quartz轻松完成定时任务

    一.背景 上次我们介绍了如何使用Spring Task进行完成定时任务的编写,这次我们使用Spring整合Quartz的方式来再一次实现定时任务的开发,以下奉上开发步骤及注意事项等. 二.开发环境及必 ...

  8. eh-admin一套前后端一体的轻量级后台管理系统

    https://gitee.com/DawnYang/eh-admin 主要技术 后端技术:Spring Boot,Apache Shiro,MyBatis-Plus等: 前端技术:Jquery,La ...

  9. MySQL 慢 SQL & 优化方案

    1. 慢 SQL 的危害 2. 数据库架构 & SQL 执行过程 3. 存储引擎和索引的那些事儿 3.1 存储引擎 3.2 索引 4. 慢 SQL 解决之道 4.1 优化分析流程 4.2 执行 ...

  10. MySQL-存储引擎-1

    一.MySQL存储引擎 mysql> create table country( -> country_id smallint unsigned not null auto_increme ...