当前位置: 首页 > news >正文

随机爬树题解

随机爬树题解

题目传送门

更好的阅读体验

\(n^2\) 暴力:

思路:

  • 求期望,即求所有点的权值乘上概率后的和,即:

\[ans=\sum_{u \in V}{P_u a_u} \]

  • 求每个点的概率 \(P_u\)

    • 由题,令走到父亲的概率为 \(P_f\),走到儿子 \(s\) 的概率则为 \(P_f \times \frac{w_s}{sum_f}\)(其中 \(sum_f\)\(f\) 所有儿子的 \(w\) 之和)。
  • 统计答案:

    • \(ans_u\) 表示 \(u\) 子树(不含 \(u\) 本身)的答案之和,最终答案为 \(ans_1+a_1\)
    • 暴力修改,跑 DFS 暴力求和即可。

代码:

::::success[代码:]

//n^2暴力 60pts
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e5+5,Mod=998244353;
int n,q,fa[N];
ll sum[N],inv[N],w[N],a[N];
ll p[N],ans[N];
vector <int> e[N];
ll qpow(ll a,ll b){ll res=1;while(b){if(b&1) (res*=a)%=Mod;(a*=a)%=Mod;b>>=1;}return res%Mod;
}
void dfs(int u){ans[u]=0;inv[u]=qpow(sum[u],Mod-2);for(int i=0;i<e[u].size();i++){int v=e[u][i];p[v]=p[u]*w[v]%Mod*inv[u]%Mod;dfs(v);(ans[u]+=(ans[v]+p[v]*a[v]%Mod)%Mod)%=Mod;}
}
int main(){scanf("%d",&n);for(int i=2;i<=n;i++){scanf("%d",&fa[i]);e[fa[i]].push_back(i);}for(int i=1;i<=n;i++){scanf("%lld",&w[i]);(sum[fa[i]]+=w[i])%=Mod;}for(int i=1;i<=n;i++){scanf("%lld",&a[i]);}p[1]=1;dfs(1);printf("%lld\n",(ans[1]+a[1])%Mod);scanf("%d",&q);int u;ll ww,aa;for(int i=1;i<=q;i++){scanf("%d",&u);sum[fa[u]]=(sum[fa[u]]-w[u]+Mod)%Mod;scanf("%lld%lld",&w[u],&a[u]);sum[fa[u]]=(sum[fa[u]]+w[u])%Mod;dfs(1);printf("%lld\n",(ans[1]+a[1])%Mod);}return 0;
}

::::

优化后正解:

思路:

  • 每次修改 \(u\) 只对 \(f\) 的整棵子树产生影响,故用线段树维护子树和。

  • 考虑有哪些影响:

    • \(w_u\) 修改为 \(ww\),使得 \(sum_f\) 发生改变,故整棵子树的概率都会变化:

      1. 对于 \(f\) 子树中每个节点 \(t\)(不含 \(f\)),原概率为 \(P_t=P_{fa_t}\times \frac{w_t}{sum_{fa_t}}\),修改后变为 \(P_t'=P_{fa_t}\times \frac{w_t}{sum_{fa_t}-w_u+ww}\)

        \[P_t'=P_t\times\frac{sum_{fa_t}}{sum_{fa_t}-w_u+ww} \]

        则有 \(\Delta P=\frac{sum_{fa_t}}{sum_{fa_t}-w_u+ww}\)

      2. 对于点 \(u\),原概率为 \(P_u=P_f\times \frac{w_u}{sum_f}\),修改后变为 \(P_u'=P_f \times \frac{ww}{sum_f-w_u+ww}\)

        \[P_u'=P_u \times \frac{ww}{wu} \times \Delta P \]

        则有 \(\Delta w=\frac{ww}{wu}\)

      3. 对于 \(u\) 子树中的每个点 \(t\)(不含 \(u\)),原概率为 \(P_t=P_{fa_t}\times \frac{w_t}{sum_{fa_t}}\),修改后变为 \(P_t'=P_{fa_t}\times \Delta w \times \frac{w_t}{sum_{fa_t}}\)

    • \(a_u\) 修改为 \(aa\),只对 \(u\) 的贡献产生影响,原贡献为 \(ans=P_u \times a_u\),修改后变为 \(ans'=P_u \times aa\),即:

      \[ans'=ans \times \frac{aa}{au} \]

  • 综上,变化有:

    • \(P_t'=P_t\times\frac{sum_{fa_t}}{sum_{fa_t}-w_u+ww}\)
    • \(P_u'=P_u \times \frac{ww}{wu} \times \frac{sum_{fa_t}}{sum_{fa_t}-w_u+ww}\)
    • \(P_t'=P_{fa_t}\times \frac{ww}{wu} \times \frac{w_t}{sum_{fa_t}}\)
    • \(ans'=ans \times \frac{aa}{au}\)

    其中操作 \(1\)\(2\)\(2\)\(3\) 可以合并。

代码:

::::success[代码:]

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e5+5,Mod=998244353;
int n,q,fa[N];
ll sum[N],w[N],a[N],p[N],val[N];
int tid,dfn[N],siz[N];
vector <int> e[N];
struct Tree{ll sum,tag;
}tr[N<<2];
ll qpow(ll a,ll b){ll res=1;while(b){if(b&1) (res*=a)%=Mod;(a*=a)%=Mod;b>>=1;}return res%Mod;
}
ll inv(ll x){return qpow(x,Mod-2);
}
void dfs(int u){dfn[u]=++tid;val[tid]=p[u]*a[u]%Mod;siz[u]=1;for(int i=0;i<e[u].size();i++){int v=e[u][i];p[v]=p[u]*w[v]%Mod*inv(sum[u])%Mod;dfs(v);siz[u]+=siz[v];}
}
void update(int k){tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%Mod;
}
void pushdown(int k,int l,int r){tr[k<<1].sum=tr[k<<1].sum*tr[k].tag%Mod;tr[k<<1].tag=tr[k<<1].tag*tr[k].tag%Mod;tr[k<<1|1].sum=tr[k<<1|1].sum*tr[k].tag%Mod;tr[k<<1|1].tag=tr[k<<1|1].tag*tr[k].tag%Mod;tr[k].tag=1;
}
void build(int k,int l,int r){tr[k].sum=0;tr[k].tag=1;if(l==r){tr[k].sum=val[l]%Mod;return ;}int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);update(k);
}
void modify(int k,int l,int r,int x,int y,int v){if(x<=l&&r<=y){tr[k].sum=tr[k].sum*v%Mod;tr[k].tag=tr[k].tag*v%Mod;return ;}pushdown(k,l,r);int mid=(l+r)>>1;if(x<=mid) modify(k<<1,l,mid,x,y,v);if(mid<y) modify(k<<1|1,mid+1,r,x,y,v);update(k);
}
int main(){//freopen("climb2.in","r",stdin);//freopen("climb.out","w",stdout);scanf("%d",&n);for(int i=2;i<=n;i++){scanf("%d",&fa[i]);e[fa[i]].push_back(i);}for(int i=1;i<=n;i++){scanf("%lld",&w[i]);sum[fa[i]]=(sum[fa[i]]+w[i])%Mod;}for(int i=1;i<=n;i++){scanf("%lld",&a[i]);}p[1]=1;dfs(1);build(1,1,n);printf("%lld\n",tr[1].sum%Mod);scanf("%d",&q);int u;ll ww,aa;for(int i=1;i<=q;i++){scanf("%d%lld%lld",&u,&ww,&aa);if(fa[u]){/*1.f子树(除f本身):Pt=Pf*(wt/sumf)* (1/(sumf-wu+ww))*sumf2.u:pu=pf*(wu/sumf)*(ww/wu)* (1/(sumf-wu+ww))*sumf3.u子树(除u本身):Pt=Pft* (ww/wu) *(wt/sumft)*///1. 2. 修改f子树(除f本身)modify(1,1,n,dfn[fa[u]]+1,dfn[fa[u]]+siz[fa[u]]-1,inv(((sum[fa[u]]-w[u]+ww)%Mod+Mod)%Mod)%Mod*sum[fa[u]]%Mod);//2. 3.modify(1,1,n,dfn[u],dfn[u]+siz[u]-1,ww*inv(w[u])%Mod);sum[fa[u]]=((sum[fa[u]]-w[u]+ww)%Mod+Mod)%Mod;}w[u]=ww;//修改au:Pu*au* (aa/au)modify(1,1,n,dfn[u],dfn[u],aa*inv(a[u])%Mod);a[u]=aa;printf("%lld\n",tr[1].sum%Mod);}return 0;
}

::::

http://www.jsqmd.com/news/43414/

相关文章:

  • 2025年11月四川护栏厂家推荐榜:综合实力与用户口碑全面对比
  • 2025年11月人形机器人落地商排行推荐:中立评价与场景适配
  • 2025年11月四川护栏厂家推荐榜单:基于用户需求的权威对比与选择指南
  • DotMemory系列:5. 如何实现自动化抓取和应用自托管
  • 2025年国内维保服务品牌综合实力排行榜:专业制冷技术企业深度解析
  • 2025年11月会计培训班推荐榜:权威机构课程对比与用户评价分析
  • 2025年11月成都监理公司推荐榜:专业服务对比与选择指南
  • 2025 西安红木家具热门销售厂家排行,木灵生红木领衔高端定制赛道
  • 2025年11月呼叫中心系统服务商推荐榜单:五大服务商综合对比分析
  • 2025年11月临沂美容/美容培训加盟十大热门品牌:杜氏大唐专业减肥养生稳坐头把交椅
  • 2025年11月高温链条油脂公司推荐榜单及选择指南:五大品牌综合对比分析
  • 2025 最新伺服压机厂家权威推荐榜:轴承 / 全自动 / 精密 / 四柱 / C 型 / 小型 / 装配 / 压装伺服压机厂家优选
  • 国产化Excel开发组件Spire.XLS教程:使用Python将CSV文件转换为列表
  • 2025年7-9级防弹窗供货厂家权威推荐榜单:4-6级防弹窗/防弹窗/抗爆防弹窗源头厂家精选
  • 2025年11月切削液公司排行对比:从资质认证到服务能力的全面评估
  • 2025 最新推荐!飞达剥标机厂家权威排行榜,贴标 / 前推式 / 后撤式 / 片料式机型及供料器优质厂家最新测评
  • 2025年11月西安口腔医院推荐排行:基于多维度数据的客观分析
  • 2025年11月高温链条油脂公司推荐榜单及综合对比分析
  • 【IEEE出版、已连续召开6届】 2025机器人与智能制造技术国际会议 (ISRIMT 2025)
  • 2025年11月机器人减速机油脂公司推荐榜单:五家优质供应商详细对比分析
  • 建筑人必备!Navisworks 2025 协同神器 大型项目协作天花板 安装
  • 2025年11月不锈钢精密铸造厂家评价:详析各企业优势与适用场景
  • 2025年11月机器人减速机油脂公司推荐榜单与深度对比分析
  • 2025年11月不锈钢精密铸造厂家详细评测与排行解析
  • 2025年食堂承包服务十大推荐榜单:专业选择指南
  • 2025年11月不锈钢精密铸造厂家排行与选购要点全指南
  • vscode 远程连接下载失败解决
  • 深入解析:自动驾驶---基于安全走廊的端到端
  • 2025年国内靠谱的石笼网供应商口碑推荐榜,双隔板石笼网/六角石笼网/柔韧抗压石笼网/锌铝合金石笼网/镀锌低碳钢丝石笼网源头厂家怎么选择
  • 2025年11月无缝钢管推荐榜:主流供应商多维对比与选购指南