首页 > 其他分享 >P9437 『XYGOI round1』一棵树 题解

P9437 『XYGOI round1』一棵树 题解

时间:2023-08-29 23:46:29浏览次数:40  
标签:P9437 题解 ll times fa num XYGOI siz dp

首先这是一道很明显的换根 dp。

首先注意到要拼接数,所以我们可以先处理出 \(num_i=10^{x}\),使得 \(10^x > a_i > 10^{x-1}\),这样方便我们后面算贡献。

我们以这棵树为例子来推状态转移方程。

先假设 \(dp_u\) 表示以 \(1\) 为根时,从 \(u\) 的子树的点到 \(u\) 的权值和。

那么

\[dp_u=\sum_{v \in son_u} dp_v \times num_u+a_u \times siz_v \]

首先 \(dp_v \times num_u\) 是把前面已经拼好的数扩大 \(num_u\) 倍,然后 \(a_u \times siz_v\) 是 \(a_u\) 一共对包含它本身在内的子树节点数的贡献。

我们求出了以 \(1\) 为根时的贡献值后,设 \(f_u\) 表示以 \(u\) 为根时的值。

那么我们可以分为两部分考虑:

  1. 属于 \(u\) 的子树的部分,那么这一部分很明显直接加上就可以,也就是 \(dp_u\),例如上图我们已经求出了以 \(1\) 为根时的值,然后我们要从节点 \(1\) 转移到节点 \(2\),那么属于节点 \(2\) 的子树部分的贡献就是 \(dp_2\)。

  2. 不属于 \(u\) 的子树的部分,我们可以先利用 \(f_{fa}-sum\) 求出 \(fa\) 的子树中除去 \(u\) 的贡献的值,其中 \(sum\) 表示节点 \(u\) 对它的父节点即 \(fa\) 的贡献,根据我们上面的方程逆推回来可得 \(sum=dp_u \times num_{fa} + a_{fa} \times siz_u\),然后再根据这个值来计算对 \(u\) 的贡献,那么还是带入上面的方程可得对 \(u\) 的贡献为 \((f_{fa}-sum) \times num_{u} + a_u \times (siz_1 - siz_{u})\).

因此状态转移方程为

\[f_u=dp_u+num_u \times (f_{fa}-(dp_u \times num_{fa}+a_{fa} \times siz_{u})) + a_u \times (siz_1-siz_u) \]

最后的答案就是

\[\sum_{i=1}^{n} f_i \]

#include <cstdio>

typedef long long ll;

const ll N=1e6+5;
const ll mod=998244353;

ll mo(ll x) {//取模,注意负数 
	return (x%mod+mod)%mod;
}

struct edge {
	ll v,nxt;
}G[N<<1];
ll h[N],idx;

void add(ll u,ll v) {
	G[++idx].v=v;
	G[idx].nxt=h[u];
	h[u]=idx;
}

ll n,a[N];
ll siz[N],num[N];
ll dp[N],f[N];

void dfs1(ll x,ll fa) {
	siz[x]=1,dp[x]=a[x];
	for(ll i=h[x];i;i=G[i].nxt) {
		ll v=G[i].v;
		if(v==fa) continue;
		dfs1(v,x);
		siz[x]+=siz[v];
		dp[x]=mo(dp[x]+mo(mo(dp[v]*num[x])+mo(siz[v]*a[x])));
	}
}

void dfs2(ll x,ll fa) {
	if(x!=1) {
		ll t1=mo(f[fa]-mo(mo(dp[x]*num[fa])+mo(a[fa]*siz[x])));
		f[x]=mo(mo(mo((siz[1]-siz[x])*a[x])+mo(t1*num[x]))+dp[x]);
	}
	for(ll i=h[x];i;i=G[i].nxt) {
		ll v=G[i].v;
		if(v==fa) continue;
		dfs2(v,x);
	}
}

int main() {
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++) {
		scanf("%lld",&a[i]);
		num[i]=10;
		while(num[i]<=a[i]) num[i]*=10;
	}
	for(ll i=2;i<=n;i++) {
		ll x;
		scanf("%lld",&x);
		add(x,i);add(i,x);
	}
	dfs1(1,0);
	f[1]=dp[1];
	dfs2(1,0);
	ll ans=0;
	for(ll i=1;i<=n;i++) ans=mo(ans+f[i]);
	printf("%lld\n",ans);
	return 0;
}

标签:P9437,题解,ll,times,fa,num,XYGOI,siz,dp
From: https://www.cnblogs.com/Scorilon/p/17666139.html

相关文章

  • CF1862E Kolya and Movie Theatre 题解
    先注意到我们娱乐值损耗的多少只与最后一场电影有关系,所以假设最后一场电影看的下标为\(k\),那么最后就要减去\(d\timesk\)。得出这个性质之后开个小根堆反悔贪心即可,首先\(a_i<0\)的没必要考虑,对于\(a_i>0\)的,如果还没到\(m\)场电影,我们就直接往里塞就可以,如果到了,我们......
  • P8675 [蓝桥杯 2018 国 B] 搭积木 题解
    总述此题用区间dp解决,二维前缀和优化。朴素做法阶段:自上而下数每一层。状态:\(dp_{i,l,r}\)表示自上而下数第\(i\)行中在\([l,r]\)摆积木的方案数。状态转移方程:根据题意可知,若要在\([l,r]\)中摆积木,那么\([l,r]\)中不允许有\(\tt{X}\),而第\(i\)层的\([l,r]\)......
  • P7809 [JRKSJ R2] 01 序列 题解
    对于第二种操作,很容易想到只有\(1\)或\(2\)两种答案,若该区间内存在\(01\)这个子序列,那么答案为\(2\)反之为\(1\).可以通过对该\(01\)串做一个前缀和,若出现\(01\)这个子序列就累加,最后判断左右端点是否相等即可,时间复杂度\(O(n)\).对于第一种操作,\(\text{Subtest1}......
  • CF1833D Flipper 题解
    赛场上思路出来了但是代码没调出来。首先考虑右端点,很明显,要让操作后的序列字典序尽量地大,那么就要使操作后的序列第一个数尽量地大,考虑\(n\)或\(n-1\),如果\(n\)在原序列的第一个位置,那么此时无论怎么调整都无法使得它在新序列的第一个位置,此时就要考虑让\(n-1\)在新序列......
  • UVA10054 The Necklace题解
    题意给定一个无向图,其中至多有\(50\)个结点,求是否有欧拉回路。题解很明显就是一个无向图求欧拉回路的板子,我们用\(\tt{Hierholzer}\),先说存图,要明确的一个点是这个无向图里是有可能有重边的,所以我们要注意记录的时候不应是单独地记录某一条边是否存在,而是要记录某一条边的数......
  • UVA967的题解
    设\(check_i\)为\(1\simn\)中满足题意的数的数量。显然答案为\(check_j-check_{i-1}\)。注意到\(check\)能直接暴力求出来。那么就可以先把\(10^6\)范围内的所有质数求出来,然后所有数跑一遍,每个数都去旋转得出所有数后判断是否均为质数,记录下来。代码很好写。#incl......
  • 一些奇怪的题的题解
    给定\(n\),求:\[\sum_{i=1}^n\sum_{j=1}^n\frac{i+j}{\gcd(i,j)}\]思路分析:先化式子:\[\begin{aligned}\sum_{i=1}^n\sum_{j=1}^n\frac{i+j}{\gcd(i,j)}&=\sum_{d=1}^n\sum_{i=1}^n\sum_{j=1}^n\frac{i+j}{d}[\gcd(i,j)=d]\\&=\sum_{d=1}^n\s......
  • CF1774 题解
    A考虑在所有\(0\)前添加正号,在\(1\)前轮流添加正负号即可。B首先根据抽屉原理,我们可以取出最多的颜色,个数记为\(mx\),然后其余颜色可以填在\(mx\)的两两中间,最少要有\((mx-1)(k-1)\)个空位。但是只是必要的,而不是充分的。考虑有多个最大值的情况,发现这些不是作为分界......
  • RTSP/Onvif视频服务器EasyNVR视频平台设备在线但通道无法播放的问题解决方案
    EasyNVR是基于RTSP/Onvif协议的视频平台,可支持将接入的视频流进行全平台、全终端的分发,分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等格式。为了满足用户的集成与二次开发需求,我们也提供了丰富的API接口供用户调用。有需要的用户可参照官方接口文档进行操作。......
  • P3888 题解
    problem&blog。这怎么评到紫上去的啊?差不多就个上位绿吧/qd。首先出题人非常low。为什么这样说呢?因为\(nm\le50,m\len\)就是在说\(m\le7\),出题人为了不让你一眼秒掉这一题,就用这种猥琐的方法写数据范围,是不是很傻逼呢。然后就是状压DP板板题了,判断合法状态只需要......