初三年后集训测试 $T 3 $ 树上的宝藏

$$HZOI$$


·题意

· \(Description\)

蒜头君有一棵 \(n\) 个节点的树(即 \(n\) 个节点, \(n−1\) 条边的无向连通图)。树的每个节点上都有一个宝藏。蒜头君准备大动干戈,拿到这些保证。

但是在拿宝藏之前,蒜头君发现了一个问题,由于树的边的材质问题,若两个节点被一条边直接连接,为了确保安全,那么这两个节点上的宝藏最多可以拿一个。

好在同样擅长化学的巨佬--花椰妹给了蒜头君一条特殊材质的边。蒜头君可以选定一条边并将这条边的材质替换成特殊材质的边,于是为了确保安全,被这条选定的边直接相连的两个节点上的宝藏最少拿一个。

蒜头君想知道,对于每一条边,若选定这条边替换成花椰妹送给他的特殊材质的边,在确保安全的情况下,有多少种拿的方法是可行的。

· \(Input\)

第一行一个正整数 \(n\) 。

后面 \(n−1\) 行,第 \(i\) 行有每行两个正整数 \(u\) , \(v\) 代表第 \(i−1\) 条边连接着点 \(u\) 和点 \(v\) 。

· \(Output\)

\(n-1\) 行 , 每行一个数,代表此边为特殊边时的方案数,输出的是对 \(998244353\) 取模的余数 。


·题解


·分析

其实换根还是很好想的。

先不考虑特殊边。

先定义一个 \(dp\) 表示在以 \(1\) 为根的情况下,以 \(i\) 为根的子树的方案数。

\(dp\) 开两维,第一维是 \(i\) , 第二维是 $ 0 || 1 $ , \(0\) 代表此位置选 \(0\) , \(1\) 同上。

易得出:

\[dp[ \ i \ ][ \ 0 \ ] \times = ( dp[ \ j \ ][ \ 0 \ ] + dp[ \ j \ ][ \ 1 \ ] ) ;
\]
\[dp[ \ i \ ][ \ 1 \ ] \times = dp[ \ j \ ][ \ 0 \ ]
\]

然后我们在定义一个定义方式与 \(dp\) 相同的 \(f\) 数组 , 表示以 \(i\) 为根的整棵树的方案数。

定义前驱结点即后继节点的直系父亲 \(x\), 后继节点即儿子 \(y\).

我们假设(或可以看做已知)你已知 \(f_{x,0 \ and \ 1}\) ,因为你是要打 \(DFS\) 的, 那么我们可以在进这一遍递归之前求出之。

那么, $$ f_{ y , 1 } = \frac{ f_{x,0} }{ dp_{y,1}+dp_{y,0}} \times dp_{y,1}$$

\[f_{ y , 0 } = \left( \frac{ f_{x , 1}}{dp_{y,0}} + \frac{f_{ x , 0 } }{dp_{y,1} + dp_{y,0} } \right) \times dp_{y,0}
\]

解释一下:

在你已知 \(x\) 是根的情况下,当 \(y\) 要取 \(1\) 时,由于一条边上至多选一个点,因此 \(x\) 取 \(0\) ;

当 \(x\) 取 \(0\) 时看上面 \(dp\) 数组的式子,你要求无 \(y\) 的方案数再乘以 \(y\) 取零的方案数;

\(y\) 取零同上。

然后推一下当边 \(i\) 是特殊边时的时候。

这时 \(f\) 和 \(dp\) 均已知,考虑所有的情况:

\(x,y\) 分别是树根(令此特殊边为树根至其儿子的路径)

  1. \(x\) 取一, \(y\) 取一

则此时:

\[ans = \frac{f_{x,1}}{dp_{y,0}} \times dp_{y,1}
\]
  1. 当 \(x\) 取一, \(y\) 取零时
\[ans = \frac{f_{x,1}}{dp_{y,0}}\times dp_{y,0}
\]

3.当 \(x\) 取零 , \(y\) 取一时

\[ans=\frac{f_{x,0}}{dp_{y,0}+dp_{y,1}} \times dp_{y,1}
\]
\[\]

· \(Code\)

点击查看代码
#include <bits/stdc++.h>
#define qcin cin
#define qcout cout
#define int long long
using namespace std ;
const int N = 3e5 + 10 ;
const int mod = 998244353 ;
int dp[ N ][ 2 ] , f[ N ][ 2 ] ;
int head[ N ] , cnt , n ;
int father[ N ] ;
class node
{
public :
int xe , ye ;
}pe[ N ] ;
class edge
{
public:
int next , to ;
}e[ N ] ;
int Quick_Pow( int alpha , int beta )
{
int ans = 1 ;
while ( beta > 0 )
{
if( beta & 1 ) ans = ( ans * alpha ) % mod ;
beta >>= 1 ;
alpha = ( alpha * alpha ) % mod ;
}
return ans ;
}
int inv( int alpha )
{
return ( Quick_Pow( alpha , mod - 2 ) ) ;
}
inline void add( int x , int y )
{
cnt ++ ;
e[ cnt ].to = y ;
e[ cnt ].next = head[ x ] ;
head[ x ] = cnt ;
}
void dfs1( int x , int fa )
{
dp[ x ][ 0 ] = dp[ x ][ 1 ] = 1 ;
for ( int i = head[ x ] ; i ; i = e[ i ].next )
{
int y = e[ i ].to ;
if( y != fa )
{
father[ y ] = x ;
dfs1( y , x ) ;
dp[ x ][ 0 ] = ( dp[ x ][ 0 ] * ( dp[ y ][ 0 ] + dp[ y ][ 1 ] ) ) % mod ;
dp[ x ][ 1 ] = ( dp[ y ][ 0 ] * dp[ x ][ 1 ] ) % mod ;
}
}
}
void dfs2( int x , int fa )
{
for ( int i = head[ x ] ; i ; i = e[ i ].next )
{
int y = e[ i ].to ;
if( y != fa )
{
f[ y ][ 1 ] = f[ y ][ 0 ] = 1 ;
int inver0 = inv( dp[ y ][ 0 ] ) , inver1 = inv( dp[ y ][ 1 ] + dp[ y ][ 0 ] ) ;
int bemod1 = ( ( f[ x ][ 1 ] ) * ( inver0 ) ) % mod ;
int bemod2 = ( f[ x ][ 0 ] * ( inver1 ) ) % mod ;
f[ y ][ 1 ] = ( dp[ y ][ 1 ] * bemod2 ) % mod ;
f[ y ][ 0 ] = ( dp[ y ][ 0 ] * ( bemod1 + bemod2 ) ) % mod ;
dfs2( y , x ) ;
}
}
}
inline void Check_Shadow( int x , int y )
{
int inv_y_0 , inv_y_1 , inv_y_01 ;
inv_y_0 = inv( dp[ y ][ 0 ] ) ;
inv_y_1 = inv( dp[ y ][ 1 ] ) ;
inv_y_01 = inv( dp[ y ][ 1 ] + dp[ y ][ 0 ] ) ;
int ans = 0 ;
ans = ( ans + ( ( ( f[ x ][ 1 ] * inv_y_0 ) % mod ) * dp[ y ][ 1 ] ) % mod ) ;
ans = ( ans + ( ( ( f[ x ][ 0 ] * inv_y_01 ) % mod ) * dp[ y ][ 1 ] ) % mod ) ;
ans = ( ans + f[ x ][ 1 ] ) % mod ;
cout << ans << '\n' ;
}
signed main( )
{
#ifndef ONLINE_JUDGE
freopen( "1.in" , "r" , stdin ) ;
freopen( "1.out" , "w" , stdout ) ;
#endif
cin >> n ;
int x , y ;
for ( int i = 1 ; i < n ; ++ i )
{
cin >> x >> y ;
pe[ i ].xe = x ;
pe[ i ].ye = y ;
add( x , y ) ; add( y , x ) ;
}
int roo = 1 ;
dfs1( roo , 0 ) ;
f[ 1 ][ 1 ] = dp[ 1 ][ 1 ] ;
f[ 1 ][ 0 ] = dp[ 1 ][ 0 ] ;
dfs2( 1 , 0 ) ;
for ( int i = 1 ; i < n ; ++ i )
{
if( father[ pe[ i ].ye ] != pe[ i ].xe )
{
swap( pe[ i ].xe , pe[ i ].ye ) ;
}
Check_Shadow( pe[ i ].xe , pe[ i ].ye ) ;
}
}

· 结尾撒花 \(\color{pink}✿✿ヽ(°▽°)ノ✿\)

初三年后集训测试T3---树上的宝藏的更多相关文章

  1. noip2019集训测试赛(二十一)Problem B: 红蓝树

    noip2019集训测试赛(二十一)Problem B: 红蓝树 Description 有一棵N个点,顶点标号为1到N的树.N−1条边中的第i条边连接顶点ai和bi.每条边在初始时被染成蓝色.高桥君 ...

  2. FJ省队集训最终测试 T3

    思路:状态压缩dp,f[i][j[[k]代表i行j列这个格子,连续的状态为k,这个连续的状态是什么?就是下图 X格子代表我当前走到的地方,而这里的状态就是红色部分,也就是连续的一段n的状态,我们是分每 ...

  3. [2016北京集训测试赛15]statement-[线段树+拆环]

    Description Solution 由于题目要求,将a[i]->b[i](边权为i)后所得的图应该是由森林和环套树组合而成. 假如是树形结构,所有的t[i]就直接在线段树t[i]点的dfs ...

  4. 安徽师大附中%你赛day5 T3 树上行走 解题报告

    树上行走 题目背景 \(\mathrm{Smart}\) 的脑洞非常大, 经常幻想出一些奇怪的东西. 题目描述 某一天,\(\mathrm{Smart}\) 幻想出了一棵没有边际的二叉树,脑补着在那棵 ...

  5. noip2017集训测试赛(十一)Problem C: 循环移位

    题面 Description 给定一个字符串 ss .现在问你有多少个本质不同的 ss 的子串 t=t1t2⋯tm(m>0)t=t1t2⋯tm(m>0) 使得将 tt 循环左移一位后变成的 ...

  6. noip2017集训测试赛(三)Problem C: MST

    题面 Description 给定一个n个点m条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为无限大, ...

  7. 2016集训测试赛(十九)Problem C: 无聊的字符串

    Solution 傻X题 我的方法是建立后缀后缀树, 然后在DFS序列上直接二分即可. 关键在于如何得到后缀树上每个字符对应的字节点: 我们要在后缀自动机上记录每个点在后缀树上对应的字母. 考虑如何实 ...

  8. BZOJ 4543 2016北京集训测试赛(二)Problem B: thr 既 长链剖分学习笔记

    Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...

  9. 2016北京集训测试赛(八)Problem C: 直径

    Solution 一个定理: 把两棵树用一条边练成一棵树后, 树的直径在原来两棵树的四个直径端点中产生. 放到这一题, 我们通过DP先求出大树中以每个点为根的子树中的直径, 再取每棵小树中与其他树有连 ...

  10. 2017省选集训测试赛(二十五)Problem B recollection

    @(XSY)[后缀数组, 启发式合并, ST表] Description Solution 后缀数组 + 启发式合并 + Sparse Table. 这是第一次写树上后缀数组. 对以每个点为根的子树统 ...

随机推荐

  1. 新版SpringBoot-Spring-Mybatis 数据库相关配置

    application.properties server.port=8081 # ========================数据库相关配置===================== sprin ...

  2. 【实操记录】MySQL二进制安装包部署

    截至2023年11月2日,MySQL社区版最新版本是8.0.35,本文详细描述了采用二进制安装的各个步骤,具有较强的参考意义,基本可作为标准步骤实施. ■ 下载数据库介质 社区版的下载地址为oracl ...

  3. Linux 文件夹和文件操作【Linux 常用命令系列一】

    〇.前言 本文首先介绍了 Linux 中文件的结构,将全部文件夹罗列并介绍了大概的用途: 然后通过实例介绍了文件夹相关的常用操作,仅供参考. 一.Linux 系统的文件结构 列一下系统全部文件夹: / ...

  4. 2023HACSP-J补测

    都快忘了自己还打过这个比赛了,所以来补一下. 完整题目在这里查看. Day0 来到郑州,寻找考场.幸好提前来了,因为考场大门就 5m 宽(HA用不用这么穷啊喂,来JZYZ不好么),开车转了 20min ...

  5. RSA加解密,Java和C#互通

    一.使用场景 Java作为服务端生成一对公私钥,C#作为客户端拥有公钥. RSA算法这里就不多做介绍了,可参考RSA算法介绍 二.规范 公私钥的形式都是base64字符串 通过公私钥加密后的字符串也是 ...

  6. 使用 Node.js 和 Express 构建基本的 Web API

    使用 Node.js 和 Express 构建 Web API Web API Node.js 中的 http 模块 创建 Express 框架 Web 应用程序 Express 框架 Express ...

  7. JavaScript小面试~~JavaScript实现图片懒加载,多方式解决加载过多问题

    图片懒加载,就是滚动页面时,图片未出现在可视局域时不加载图片,只有图片出现在可视区域才加载. 思路:通过上面一段话,实现图片懒加载需要知道: 绑定滚动事件 可视窗口高度(VH) 图片元素距离可视局域顶 ...

  8. CF1951

    A link 这个题就是讨论. 首先,如果没有\(1\)就一定可以. 如果有\(1\). 如果长度为\(2\)一定不行. \(1\)的个数为奇数不行. 如果为偶数 有一个小点:如果是\(2\)个\(1 ...

  9. bloom效果

    搜索 复制

  10. 基于.NET开源、强大易用的短链生成及监控系统

    前言 今天大姚给大家分享一个基于.NET开源(MIT License).免费.强大易用的短链生成及监控系统:SuperShortLink. 项目介绍 SuperShortLink是一个基于.NET开源 ...