初三年后集训测试T3---树上的宝藏
初三年后集训测试 $T 3 $ 树上的宝藏
·题意
· \(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\) 相同的 \(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}$$
\]
解释一下:
在你已知 \(x\) 是根的情况下,当 \(y\) 要取 \(1\) 时,由于一条边上至多选一个点,因此 \(x\) 取 \(0\) ;
当 \(x\) 取 \(0\) 时看上面 \(dp\) 数组的式子,你要求无 \(y\) 的方案数再乘以 \(y\) 取零的方案数;
\(y\) 取零同上。
然后推一下当边 \(i\) 是特殊边时的时候。
这时 \(f\) 和 \(dp\) 均已知,考虑所有的情况:
\(x,y\) 分别是树根(令此特殊边为树根至其儿子的路径)
- \(x\) 取一, \(y\) 取一
则此时:
\]
- 当 \(x\) 取一, \(y\) 取零时
\]
3.当 \(x\) 取零 , \(y\) 取一时
\]
· \(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---树上的宝藏的更多相关文章
- noip2019集训测试赛(二十一)Problem B: 红蓝树
noip2019集训测试赛(二十一)Problem B: 红蓝树 Description 有一棵N个点,顶点标号为1到N的树.N−1条边中的第i条边连接顶点ai和bi.每条边在初始时被染成蓝色.高桥君 ...
- FJ省队集训最终测试 T3
思路:状态压缩dp,f[i][j[[k]代表i行j列这个格子,连续的状态为k,这个连续的状态是什么?就是下图 X格子代表我当前走到的地方,而这里的状态就是红色部分,也就是连续的一段n的状态,我们是分每 ...
- [2016北京集训测试赛15]statement-[线段树+拆环]
Description Solution 由于题目要求,将a[i]->b[i](边权为i)后所得的图应该是由森林和环套树组合而成. 假如是树形结构,所有的t[i]就直接在线段树t[i]点的dfs ...
- 安徽师大附中%你赛day5 T3 树上行走 解题报告
树上行走 题目背景 \(\mathrm{Smart}\) 的脑洞非常大, 经常幻想出一些奇怪的东西. 题目描述 某一天,\(\mathrm{Smart}\) 幻想出了一棵没有边际的二叉树,脑补着在那棵 ...
- noip2017集训测试赛(十一)Problem C: 循环移位
题面 Description 给定一个字符串 ss .现在问你有多少个本质不同的 ss 的子串 t=t1t2⋯tm(m>0)t=t1t2⋯tm(m>0) 使得将 tt 循环左移一位后变成的 ...
- noip2017集训测试赛(三)Problem C: MST
题面 Description 给定一个n个点m条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为无限大, ...
- 2016集训测试赛(十九)Problem C: 无聊的字符串
Solution 傻X题 我的方法是建立后缀后缀树, 然后在DFS序列上直接二分即可. 关键在于如何得到后缀树上每个字符对应的字节点: 我们要在后缀自动机上记录每个点在后缀树上对应的字母. 考虑如何实 ...
- BZOJ 4543 2016北京集训测试赛(二)Problem B: thr 既 长链剖分学习笔记
Solution 这题的解法很妙啊... 考虑这三个点可能的形态: 令它们的重心为距离到这三个点都相同的节点, 则其中两个点分别在重心的两棵子树中, 且到重心的距离相等; 第三个点可能在重心的一棵不同 ...
- 2016北京集训测试赛(八)Problem C: 直径
Solution 一个定理: 把两棵树用一条边练成一棵树后, 树的直径在原来两棵树的四个直径端点中产生. 放到这一题, 我们通过DP先求出大树中以每个点为根的子树中的直径, 再取每棵小树中与其他树有连 ...
- 2017省选集训测试赛(二十五)Problem B recollection
@(XSY)[后缀数组, 启发式合并, ST表] Description Solution 后缀数组 + 启发式合并 + Sparse Table. 这是第一次写树上后缀数组. 对以每个点为根的子树统 ...
随机推荐
- OpenTelemetry 深度定制:跨服务追踪的实战技巧
背景 在上一篇<从 Dapper 到 OpenTelemetry:分布式追踪的演进之旅>中在最后提到在做一些 Trace 的定制开发. 到现在差不多算是完成了,可以和大家分享一下. 我们的 ...
- Android系统启动:2-Init篇
Android系统启动:Init篇 原文:http://gityuan.com/2016/02/05/android-init/ 概述 init进程是Linux系统中用户空间的第一个进程,进程号固定为 ...
- Ubuntu访问samba共享文件
Ubuntu访问samba共享文件 参考:https://www.cnblogs.com/Wolf-Dreams/p/11241198.html 做法 安装samba-client.cifs-util ...
- 高通mm-camera平台 Camera bring up基本调试思路
原文:https://www.cnblogs.com/thjfk/p/4086001.html 确定硬件 1.首先对照原理图,检查camera module的pin脚连接是否正确. 2.用示波器量Ca ...
- Centos 下Rabbit MQ 常用操作指令 汇总
1.rabbitmq 服务的启动停止. service rabbitmq-server start service rabbitmq-server stop 重启命令需要依次执行 stop 再 sta ...
- fpga是什么
FPGA(Field Programmable Gate Array) 现场可编程门阵列
- Oracle自定义数据类型
1 CREATE OR REPLACE FUNCTION split(p_str IN clob, 2 p_delimiter IN VARCHAR2 default (',') --分隔符,默认逗号 ...
- C# 判断字符串是否为整数
/// <summary> /// 判断一个字符串是否是正整数 /// </summary> /// <param name="s"></ ...
- 图表绘制之RepeatNode的妙用
图表绘制之RepeatNode的妙用 前言 最近接到许多大屏项目,其中有一个智慧大楼的项目,大致是由3d场景+数据图表组成,需要能监控实时数据.安防 监控.出入统计以及消防安全等功能如下图 但是在开发 ...
- njs最详细的入门手册:Nginx JavaScript Engine
原文链接:https://hi.imzlh.top/2024/07/08.cgi 关于njs 首先,njs似乎在国内外都不受关注,资料什么的只有 官网参考手册,出了个问题只能看到Github Issu ...