当前位置: 首页 > news >正文

ARC142D Deterministic Placing

ARC142D Deterministic Placing

题目大意

有一棵nnn个顶点的树,每个点上最多放一张卡片,你可以做如下操作:

  • 同时将所有的卡片移到它所在顶点的相邻的一个顶点上

一个操作我们说它是好的,当下列条件满足:

  • 每条边最多被某张卡片经过
  • 每个顶点最多被一张卡片占据

TTT可以选择一个或多个顶点来放置卡片,一个顶点放置一张卡片。他有2n−12^n-12n1种方式,求满足以下条件的方案数:
对于每个非负整数kkk

  • 它能连续进行kkk次好的操作
  • SkS_kSk表示经过刚好kkk次操作后被卡片占据的点的集合,则SkS_kSk是唯一的

题解

第一步:分树为链

我们可以发现,每一张卡片都是在两个点上反复横跳的。我们把每个反复横跳的边拿出来,那一定是若干条不相交的链。且这些链一定是以空点为顶部,有卡片的点为中部和尾部(一条链不能只有一个空点)。这些链一定能填满整棵树。

假设x,yx,yx,y为相邻的两个点且在不同的链上,为了避免重复和不合法的情况,我们做一些规定。

  • 如果xxx链的端点且yyy为链的中间点,则在第二次操作时,在yyy上的卡片可以向xxx移动,则SkS_kSk不唯一
  • 如果x,yx,yx,y都是链的顶部,则第一次操作后两条链合并成一条链,可以往两个方向移动,SkS_kSk不唯一
  • 如果x,yx,yx,y都是链的尾部,则第一次操作时xxx的位置空出了,yyy所在可以往链头或xxx移动,SkS_kSk不唯一

其余情况都是合法的。


第二步:树形DP

定义fu,if_{u,i}fu,i表示点uuuiii种状态下的方案数。各种状态如下:

  • fu,0f_{u,0}fu,0表示uuu为链身,且uuu在链上无前无后
  • fu,1f_{u,1}fu,1表示uuu为链身,且uuu在链上有前无后
  • fu,2f_{u,2}fu,2表示uuu为链身,且uuu在链上无前有后
  • fu,3f_{u,3}fu,3表示uuu为链身,且uuu在链上有前有后
  • fu,4f_{u,4}fu,4表示uuu为链头,且uuu在链上无后面的点
  • fu,5f_{u,5}fu,5表示uuu为链头,且uuu在链上有后面的点
  • fu,6f_{u,6}fu,6表示uuu为链尾,且uuu在链上无后面的点
  • fu,7f_{u,7}fu,7表示uuu为链尾,且uuu在链上有后面的点

有前或有前面的点即存在链头,有后或有后面的点即存在链尾。

为了防止在转移的时候计算重复,我们还需要定义gu,ig_{u,i}gu,i。假设当前枚举的是uuu的各个儿子,且枚举到的儿子为vvv,则fu,if_{u,i}fu,i表示点uuu在统计vvv之前的各种状态的方案数,ggg表示统计vvv之后的方案数,则可以用fu,if_{u,i}fu,ifv,if_{v,i}fv,i来更新ggg,在vvv的贡献计算完之后再将ggg的值赋值给fff,然后计算uuu的下一个儿子。

因为状态比较多,所以转移式也比较多。除去不合法的情况,有202020种转移方法,具体见代码。

对于每个点,状态0,4,60,4,60,4,6fff的初值为111。最后的答案为f1,3+f1,5+f1,7f_{1,3}+f_{1,5}+f_{1,7}f1,3+f1,5+f1,7


总结

这道题主要是用树形DP,考虑各种状态来进行状态转移。时间复杂度为O(n)O(n)O(n)

注:代码中gt(v1,v2,v3)gt(v1,v2,v3)gt(v1,v2,v3)表示gu,v1=fu,v2×fv,v3g_{u,v1}=f_{u,v2}\times f_{v,v3}gu,v1=fu,v2×fv,v3vvvuuu的儿子。这一步即用uuu点的状态v2v2v2fffvvv点的状态v2v2v2fff值更新ggg的状态v1v1v1

code

#include<bits/stdc++.h>
using namespace std;
int n,x,y,tot=0,d[500005],l[500005],r[500005];
long long v[10],f[200005][8];
long long mod=998244353;
void add(int xx,int yy){l[++tot]=r[xx];d[tot]=yy;r[xx]=tot;
}
void pt(int v1,int v2,int v3){v[v1]=(v[v1]+f[x][v2]*f[y][v3]%mod)%mod;
}
void dfs(int u,int fa){f[u][0]=f[u][4]=f[u][6]=1;for (int i=r[u];i;i=l[i]){if(d[i]==fa) continue;dfs(d[i],u);for (int j=0;j<8;j++) v[j]=0;x=u;y=d[i];pt(0,0,3);pt(1,0,4);pt(1,0,1);pt(1,1,3);pt(2,0,6);pt(2,0,2);pt(2,2,3);pt(3,2,4);pt(3,1,6);pt(3,1,2);pt(3,2,1);pt(3,3,3);pt(4,4,7);pt(5,5,7);pt(5,4,2);pt(5,4,6);pt(6,6,5);pt(7,7,5);pt(7,6,1);pt(7,6,4);for(int j=0;j<8;j++) f[u][j]=v[j];}
}
int main()
{scanf("%d",&n);for(int i=1;i<n;i++){scanf("%d%d",&x,&y);add(x,y);add(y,x);}dfs(1,0);printf("%lld",(f[1][3]+f[1][5]+f[1][7])%mod);return 0;
}
http://www.lryc.cn/news/22602.html

相关文章:

  • 阶段八:服务框架高级(第二章:分布式事务)
  • RPC异步化原理
  • C# 多窗口切换的实现
  • 【深度学习】RNN
  • 招聘岗位,机会难得
  • web打印的几种方法(2023)
  • 代码随想录算法训练营day44 | 动态规划之完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ
  • IntelliJ IDEA 实用插件推荐(包含使用教程)
  • WideDeep模型
  • nacos集群模式+keepalived搭建高可用服务
  • 吉利「银河」负重突围
  • QT之图形视图框架概述——Graphics View Framework
  • 【SQL开发实战技巧】系列(二十二):数仓报表场景(上) 从分析函数效率一定快吗聊一聊结果集分页和隔行抽样实现方式
  • 小米无线AR眼镜探索版细节汇总
  • Web3中文|Litra:简洁而优美的NFT流动性协议,能给NFT市场带来什么?
  • SSL证书对虚拟主机的用处有哪些?
  • SpringCloud之MQ笔记分享
  • 动态规划背包问题
  • OpenCV4.x图像处理实例-张嘴和闭嘴检测
  • 软考高级系统分析师系列论文之十二:论实时控制系统与企业信息系统集成在工业控制的常规应用
  • 蓝桥杯入门即劝退(二十三)货物摆放问题
  • 经验之谈——指标异常了怎么办?
  • 影视领域解说电影怎样做才会更加出彩?
  • 【Spring6】| Spring对IoC的实现(核心重点)
  • 部门来了个测试工程师,听说是00后,实在是太卷了.....
  • 冲冲冲,力扣javascript刷题——数组总结
  • 使用kotlin编写html dsl框架
  • 【谷粒学院】MybatisPlus(1~17)
  • C++的输入输出
  • RNN相关知识总结