[题解] Atcoder ARC 142 D Deterministic Placing 结论,DP
题目
(可能有点长,但是请耐心看完,个人认为比官方题解好懂:P)
首先需要注意,对于任意节点i上的一个棋子,如果在一种走法中它走到了节点j,另一种走法中它走到了节点k,那么这两种走法进行完后,棋子占据的节点集合不可能相同,因为在这两种走法中,节点i必有两个子树中的棋子数量不同。所以,题目中的"被占据的集合唯一"等价于"每个棋子走向的节点唯一"。
根据题意,一个初始状态合法当且仅当这个状态可以进行任意次操作,且进行k步操作后,接下来一步操作唯一(不管这样走之后,是否还能进行无限次操作)。先不考虑"唯一",只考虑怎么使得可以进行无限次操作。我们可以把树分成一些链,每条链初始有一个端点是空的,其他节点都被棋子占据。第一步操作时,把每条链上的每个棋子,都往这条链上的空节点方向移动一步。后面的每一步操作都可以在这两个状态之间反复横跳,满足了"无限次"的要求。现在把"唯一"的条件加进来,发现树上的每个节点都必须恰好被一条链覆盖到,不然肯定存在一个没被覆盖的节点i,使得在某一步中可以把一个本应该走到其他位置的棋子移到这个点上,使得方案不唯一。
如果一个状态合法,唯一的操作方案就是:每条链上的棋子在这条链上左右横跳。现在来看看哪些"链划分"是不合法的(操作方案不唯一)。我们把每条链没有棋子的端点称为"0端",有棋子的端点称为"1端",这两个统称端点;其它点称为中间点。
先给出结论:两个相邻节点x、y,如果出现以下情况之一,这种状态就不合法,否则合法:1.一个是中间点,一个是端点,且属于不同的链;2.两个点都是1端(属于不同的链);3.两个点都是0端(显然也属于不同的链)。
证明:
1.出现以上情况的一定不合法
如果x是中间点且y是端点,不属于同链,如果y是1则x可以在第一步向y移动,y是0则x可以在第二步向y移动,均不唯一
都是1端,则可以合并成一条链,并扔掉其中一条链的0端,不唯一
都是0端,则移动一次后可以合并成一条链
2.不出现的一定合法
只需要证明任意一种没有上述情况的状态,第一步操作都唯一。因为操作一次后达到的状态是与其对称的,再操作一次又回到了这个状态。
考虑一个中间节点会不会不守本分,跑到其他的链去。那肯定是跑到了另一条链的一个中间节点,原本要到这个点的棋子就必须找另一条路,它可以走到另一条链,也可以向着本链的1端走一步,第一种走法循环了,所以若干次后总会走上第二种。走上第二种后,类似的,总能规约到一个1端棋子必须走到别的链(的0端)。原来要走到这个0端节点的棋子是在一个中间位置上的,它又需要走到别的链,或者向本链1端走\(\cdots\)
发现陷入了死循环,所以总有一个点找不到出路,所以方案不唯一的情况此时不会出现。
接下来对合法的链划分计数。考虑树形dp,dp过程中不考虑每条链的方向(即忽略0端和1端的位置)
dp[*][0]&:当前是中间节点,所在链的两端点都在子树内\\
dp[*][1]&:中间节点,链只有一个端点在子树内\\
dp[*][2]&:端点,与之匹配的端点不在子树内\\
dp[*][3]&:端点,匹配的端点在子树内
\end{align}
\]
转移比较简单,不一一赘述。考虑怎么加入每条链方向的影响,如果两条链端点相邻,则在这两条链间连边。最后每一个连通块都有2种方案。对于任意一个中间节点,它在树上的儿子中除了1或2个,其他都跟它属于不同的连通块,当前dp到的节点为中间节点时乘上对应方案数即可。
时间复杂度\(O(n)\)。
点个赞求求了,/kel
点击查看代码
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define pb push_back
#define fi first
#define se second
#define mpr make_pair
using namespace std;
const LL MOD=998244353;
LL qpow(LL x,LL a)
{
LL res=x,ret=1;
while(a>0)
{
if((a&1)==1) ret=ret*res%MOD;
a>>=1;
res=res*res%MOD;
}
return ret;
}
LL n,dp[200010][4],dp2[200010][3],suf[200010];
vector <LL> g[200010];
void dfs(LL pos,LL par)
{
vector <LL> son;
rep(i,g[pos].size()) if(g[pos][i]!=par)
{
dfs(g[pos][i],pos);
son.pb(g[pos][i]);
}
//2
dp[pos][2]=1;rep(i,son.size()) (dp[pos][2]*=dp[son[i]][3])%=MOD;
//3
suf[0]=1;rep(i,son.size()) suf[i+1]=suf[i]*dp[son[son.size()-i-1]][3]%MOD;
LL bas=1;
rep(i,son.size())
{
(dp[pos][3]+=(dp[son[i]][1]+dp[son[i]][2])%MOD*bas%MOD*suf[son.size()-i-1])%=MOD;
(bas*=dp[son[i]][3])%=MOD;
}
//1
suf[0]=1;rep(i,son.size()) suf[i+1]=suf[i]*dp[son[son.size()-i-1]][0]%MOD;
bas=1;
rep(i,son.size())
{
(dp[pos][1]+=(dp[son[i]][1]+dp[son[i]][2])%MOD*bas%MOD*suf[son.size()-i-1])%=MOD;
(bas*=dp[son[i]][0])%=MOD;
}
//0
rep(i,son.size()+3) rep(j,3) dp2[i][j]=0;
dp2[0][0]=1;
rep(i,son.size()) rep(j,3)
{
if(j<2) (dp2[i+1][j+1]+=dp2[i][j]*(dp[son[i]][1]+dp[son[i]][2]))%=MOD;
(dp2[i+1][j]+=dp2[i][j]*dp[son[i]][0])%=MOD;
}
dp[pos][0]=dp2[son.size()][2];
LL mul=(LL)son.size()-2;
if(mul>0) (dp[pos][0]*=qpow(2,mul))%=MOD;
++mul;
if(mul>0) (dp[pos][1]*=qpow(2,mul))%=MOD;
}
int main()
{
cin>>n;
LL x,y;
rep(i,n-1)
{
scanf("%lld%lld",&x,&y);
g[x].pb(y);g[y].pb(x);
}
dfs(1,0);
cout<<(dp[1][0]+dp[1][3])*2LL%MOD<<endl;
return 0;
}
[题解] Atcoder ARC 142 D Deterministic Placing 结论,DP的更多相关文章
- [题解] Atcoder ARC 142 E Pairing Wizards 最小割
题目 建图很妙,不会. 考虑每一对要求合法的巫师(x,y),他们两个的\(a\)必须都大于\(min(b_x,b_y)\).所以在输入的时候,如果\(a_x\)或者\(a_y\)小于\(min(b_x ...
- 【题解】POJ2279 Mr.Young′s Picture Permutations dp
[题解]POJ2279 Mr.Young′s Picture Permutations dp 钦定从小往大放,然后直接dp. \(dp(t1,t2,t3,t4,t5)\)代表每一行多少人,判断边界就能 ...
- 【题解】HDU4689 Derangement(有技巧的计数DP)
[题解]HDU4689 Derangement(有技巧的计数DP) 传送门 呵呵没告诉我多测组数,然后\(n\le 20,7000\mathrm{ms}\)我写了个状压上去T了 题目大意: 要你求错排 ...
- 【题解】Music Festival(树状数组优化dp)
[题解]Music Festival(树状数组优化dp) Gym - 101908F 题意:有\(n\)种节目,每种节目有起始时间和结束时间和权值.同一时刻只能看一个节目(边界不算),在所有种类都看过 ...
- 【题解】CF1056F Write the Contest(三分+贪心+DP)
[题解]CF1056F Write the Contest(三分+贪心+DP) 最优化问题的三个解决方法都套在一个题里了,真牛逼 最优解应该是怎样的,一定存在一种最优解是先完成了耗时长的任务再干别的( ...
- [题解] Atcoder Regular Contest ARC 147 A B C D E 题解
点我看题 A - Max Mod Min 非常诈骗.一开始以为要观察什么神奇的性质,后来发现直接模拟就行了.可以证明总操作次数是\(O(nlog a_i)\)的.具体就是,每次操作都会有一个数a被b取 ...
- 【题解】Atcoder ARC#96 F-Sweet Alchemy
首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...
- 【题解】Atcoder ARC#90 F-Number of Digits
Atcoder刷不动的每日一题... 首先注意到一个事实:随着 \(l, r\) 的增大,\(f(r) - f(l)\) 会越来越小.考虑暴力处理出小数据的情况,我们可以发现对于左端点 \(f(l) ...
- 【题解】Atcoder ARC#94 F-Normalization
再次膜拜此强题!神级性质之不可能发现系列收藏++:首先,对于长度<=3的情况,我们采取爆搜答案(代码当中是打表).对于长度>=4的情况,则有如下几条玄妙的性质: 首先我们将 a, b, c ...
随机推荐
- led跑马灯(模糊时钟ambiguous color,非法字符 non printable character,寄存器初值,计数器计数注意事项)
1.设计定义 让8个led以100ns的速度循环闪烁. 2.设计输入 循环闪烁,还是周期问题,用时钟驱动,所以需要一个时钟信号clk.再给一个复位输入reset,八个输出led信号. 每100ns只有 ...
- JUC源码学习笔记3——AQS等待队列和CyclicBarrier,BlockingQueue
一丶Condition 1.概述 任何一个java对象都拥有一组定义在Object中的监视器方法--wait(),wait(long timeout),notify(),和notifyAll()方法, ...
- Dubbo源码(一) - SPI使用
为什么学SPI Dubbo 的可扩展性是基于 SPI 去实现的,而且Dubbo所有的组件都是通过 SPI 机制加载. 什么是SPI SPI 全称为 (Service Provider Interfac ...
- 2506-nginx的配置-域名分发与负载均衡(只有配置无原理)
nginx的安装 Windows7:官网下载,是一个压缩包,运行解压缩后的exe文件即启动了nginx,需注意的是,Windows(win7)的80端口默认被微软的IIS占用,需改成别的端口,例如80 ...
- PDF 拆分/合并
不会真的有人会去下载那些广告免费,实则要收会员费的黑心软件来进行PDF的拆分合并吧??? 在下载两个均不能免费实现PDF自由拆分.合并,以及PDF打印方式会增加文件大小的情况下,一个合格的程序员肯定不 ...
- AI目标分割能力,无需绿幕即可实现快速视频抠图
绿幕抠图是影视制作过程中常见的技术手段,常用于视频中抠除并替换背景,通过后期加工实现视频剪辑制作的更多可能性.然而,绿幕抠图技术制作成本费时费力,无法应用于日常生活. 华为视频编辑服务近期上线目标分割 ...
- 选择结构——嵌套 if 控制语句
1.嵌套 if 控制语句 概念: 在 if 控制语句中又包含一个或多个 if 控制语句的简称为嵌套 if 控制语句.嵌套 if 控制语句可以通过外层语句和内层语句的协作,来增强程序的灵活性. 语法格式 ...
- HCIA-Datacom 3.4 实验四:实现VLAN间通信实验
实验介绍: 划分VLAN后,不同VLAN的用户间不能二层互访,这样能起到隔离广播的作用.但实际应用中,不同VLAN的用户又常有互访的需求,此时就需要实现不同VLAN的用户互访,简称VLAN间互访.华为 ...
- 造数字(数位DP)
题面 JZM 想要创造两个数字 x 和 y,它们需要满足 x or y = T,且Lx ≤ x ≤ Rx, Ly ≤ y ≤ Ry,JZM 想知道 x and y 有多少种可能的不同的取值.若有多组 ...
- Queue-jumpers - 平衡树
题面 Ponyo and Garfield are waiting outside the box-office for their favorite movie. Because queuing i ...