一、题目描述:
有
有一个正整数
在游戏的每一轮,所有人同时都把自己手上的球全部传给自己的传球目标。
求游戏结束之后,每个人手上的期望球的数量。答案对
数据范围:
二、解题思路:
首先我们发现这个期望可以转化为求和,最后乘上
这类轮数很多的题有两条路可以走(就我的认知而言):找规律 & 倍增
这题的状态显然:
而转移的过程大概是比较套路的,但是这是我第一次做这样的题,所以还是分析一下:
令
画个图不难发现:
虽然统计自己的儿子不好统计,但是只要每个点向自己的
现在考虑经过了
显然
于是单次贡献也能
三、完整代码:
1 #include<iostream> 2 #define N 200010 3 #define ll long long 4 #define mod 998244353 5 #define rep(i,l,r) for(ll i=l;i<=r;i++) 6 using namespace std; 7 ll n,k,inv,fa[N],val[N],tp[N],ans[N]; 8 ll ksm(ll base,ll q){ 9 ll res=1;base%=mod;while(q){ 10 if(q&1) res*=base,res%=mod; 11 base*=base;base%=mod;q>>=1; 12 }return res; 13 } 14 void add(ll &a,ll b){ 15 a+=b; if(a>=mod) a-=mod; 16 } 17 int main(){ 18 ios::sync_with_stdio(false); 19 cin.tie(0);cout.tie(0); 20 cin>>n>>k; inv=ksm(k,mod-2); 21 rep(i,1,n) cin>>fa[i]; 22 rep(i,1,n) cin>>val[i]; 23 rep(i,1,n) add(tp[fa[i]],val[i]); 24 rep(i,1,n) val[i]=tp[i]; 25 while(k){ 26 if(k&1){ 27 rep(i,1,n) add(ans[i],val[i]); 28 rep(i,1,n) tp[i]=0; 29 rep(i,1,n) add(tp[fa[i]],val[i]); 30 rep(i,1,n) val[i]=tp[i]; 31 } 32 rep(i,1,n) tp[i]=0; 33 rep(i,1,n) add(tp[fa[i]],val[i]); 34 rep(i,1,n) add(val[i],tp[i]); 35 rep(i,1,n) tp[i]=fa[fa[i]]; 36 rep(i,1,n) fa[i]=tp[i]; k>>=1; 37 } 38 rep(i,1,n) cout<<ans[i]*inv%mod<<" "; 39 return 0; 40 }
四、写题心得:
有一些倍增的题一直没时间写博客,今天总结一下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了