题解 P9437『XYGOI round1』一棵树
换根 DP。
本蒟蒻最初没想到换根,把自己写自闭了...
定义 为子树 中的每个结点走到 的贡献和, 为大于 的最小的 的幂次方数, 为 。
转移方程为:。
再定义 为除去子树 其他的所有点到 的贡献和。
转移方程为:。
然后答案加上 。
复杂度 。
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,mod=998244353;
ll n,a[N],f[N],g[N],siz[N],sum[N],ans;
vector<int>adj[N];
ll get(ll x){
if(x==0)return 10;
ll res=1;
while(x){res*=10;x/=10;}
return res;
}
void dfs(int u,int lst){
siz[u]=1;
ll t=get(a[u]);f[u]=a[u];
for(int i=0;i<adj[u].size();++i){
int v=adj[u][i];if(v==lst)continue;
dfs(v,u);siz[u]+=siz[v];f[u]=(f[u]+f[v]*t+siz[v]*a[u])%mod;sum[u]=(sum[u]+f[v])%mod;
}
}
void dfs2(int u,int lst){
ll tu=get(a[u]);
for(int i=0;i<adj[u].size();++i){
ll v=adj[u][i],tv=get(a[v]);if(v==lst)continue;
g[v]=(g[u]+(sum[u]-f[v]+mod)%mod)%mod*tu+(n-siz[v])*a[u];g[v]%=mod;
ans=(ans+(g[v]+sum[v])*tv+n*a[v])%mod;
dfs2(v,u);
}
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n;for(int i=1;i<=n;++i)cin>>a[i];
for(int u=2;u<=n;++u){
int v;cin>>v;
adj[u].push_back(v);adj[v].push_back(u);
}
dfs(1,0);ans+=f[1];dfs2(1,0);
cout<<ans<<endl;
return 0;
}
本文作者:HQJ2007
本文链接:https://www.cnblogs.com/HQJ2007/p/17561568.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话