考虑到删点操作的实质是指认边的方向。

由于这是一棵树,所以有很好的性质。

我们完全可以以此从树叶开始,往上拓扑进行,按照对某个数的取膜的大小来进行操作。

由此可知,除了 \(1\) 以外,任意 \(2 \leq k\) 都有可能,且只有一种方案。

那么如何判断方案是当下的问题。

考虑到我们的的操作过程,我们发现其实在每个质数的同余系下,有且只有一个答案可能存在。

又由于 \(m = n - 1 = \sum a[i]\),那么我们把 \(m\) 质数分解,对这些质数的同余系进行讨论就好。

同时总方案数为 \(2 ^ {n - 1}\) ,依照容斥原理,那么 \(k = 1\) 时答案为 \(2 ^ {n - 1} - \sum_{i = 2} f[i]\)

#include<iostream>
#include<cstdio>
#include<queue>
#define ll long long
#define N 100005
#define mod 998244353 ll T;
ll n;
ll head[N],cnt;
ll in[N],iin[N];
ll a[N],b[N];
ll f[N]; struct P{
int to,next;
}e[N << 1]; inline void clear(){
for(int i = 1;i <= n;++i)
head[i] = in[i] = iin[i] = a[i] = b[i] = 0,f[i] = 0;
for(int i = 1;i <= cnt;++i)
e[i].to = e[i].next = 0;
cnt = 0; } inline void add(int x,int y){
e[++cnt].to = y;
e[cnt].next = head[x];
head[x] = cnt;
in[y] ++ ;
} inline ll qpow(ll a,ll b){
ll ans = 1;
while(b){
if(b & 1)ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
} std::queue<int>QWQ; ll vis[N]; inline ll gcd(ll x,ll y){
return (x == 0) ? y : gcd(y % x,x);
} inline ll find(ll x){//找出在该同余系下的答案。
for(int i = 1;i <= n;++i)
iin[i] = in[i],a[i] = b[i] = 0,vis[i] = 0;
for(int i = 1;i <= n;++i)
if(iin[i] == 1)//成为叶子
QWQ.push(i);
while(QWQ.size()){
int u = QWQ.front();
QWQ.pop();
vis[u] = 1;
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(vis[v])continue;
if(a[u] == 0)a[v] = (a[v] + 1) % x,b[v] ++ ;else a[u] = (a[u] + 1) % x,b[u] ++;
iin[v] -- ;
if(iin[v] == 1)
QWQ.push(v);
}
}
ll ans = b[1];
for(int i = 2;i <= n;++i)
ans = gcd(ans,b[i]);
return ans;
} int main(){
scanf("%lld",&T);
while(T -- ){
scanf("%lld",&n);
clear();
for(int i = 1;i <= n - 1;++i){
ll x,y;
scanf("%lld%lld",&x,&y);
add(x,y);
add(y,x);
}
ll m = n - 1;
for(int i = 2;i * i <= m;++i){
if(m % i == 0){
ll si = find(i);
if(si % i == 0)
f[si] = 1 ;
while(m % i == 0 && i != 1)m /= i;
}
}
if(m > 1){
ll si = find(m);
if(si % m == 0)
f[si] = 1 ;
}
f[1] = (f[1] + qpow(2,n - 1)) % mod;
for(int i = 2;i <= n;++i)
f[1] = (f[1] - f[i] + mod) % mod;
for(int i = 1;i <= n;++i)
std::cout<<f[i]<<" ";
puts("");
}
}

CF1554E You的更多相关文章

  1. Involuting Bunny! (2021.8)

      CF1555F & Submission.   Tags:「A.生成树」「B.Tricks」   分类处理询问的 trick:连接两个连通块的边显然合法,先用这些边构建生成森林.发现每条边 ...

随机推荐

  1. C++控制台应用程序一闪而过的解决方法

    Visual Studio 2017 C++控制台应用程序, 如果编译时发现黑框一闪而过,请按以下步骤操作: 右键project → 属性 → 链接器 → 系统 → 子系统,在下拉菜单中改为控制台.

  2. DM8数据库单机安装

    一.系统概要 表1 部署情况一览表 操作系统 Windows10 数据库版本 DM8(开发版) 数据库类型 单机 磁盘挂载 无 Key信息 无 二.操作系统信息检查 2.1 操作系统版本 [root@ ...

  3. try-catch-finally面试题

    try catch finally 执行顺序面试题总结 执行顺序 今天牛客网遇到这个题目,做对了,但是下面的评论却很值得看看 public class TestTry { public int add ...

  4. SpringCloud 2020.0.4 系列之 Feign

    1. 概述 老话说的好:任何问题都有不止一种的解决方法,当前的问题没有解决,只是还没有发现解决方法,而并不是无解. 言归正传,之前我们聊了 SpringCloud 的服务治理组件 Eureka,今天我 ...

  5. [技术博客] 通过ItemTouchHelper实现侧滑删除功能

    通过ItemTouchHelper实现侧滑删除功能 一.效果 二.具体实现 demo中演示的这种左滑删除的效果在手机APP中比较常用,安卓也为我们提供了专门的辅助类ItemTouchHelper来帮助 ...

  6. 关于QGIS的插件开发(C++)

    关于C++插件的开发材料较少,根据网上的指导,我采用了早期版本的插件模板生成的方法来创建QGIS的插件,其方法是从以前版本(2.18.25)里面拷贝插件模板的方法进行,具体的执行步骤为 1.拷贝文件 ...

  7. 嵌入式单片机stm32之DMA实验

    一. 对于大容量的STM32芯片有2个DMA控制器,控制器1有7个通道,控制器2有5个通道 每个通道都可以配置一些外设的地址. 二. 通道的配置过程: 1. 首先设置CPARx寄存器和CMARx寄存器 ...

  8. linux中解压.tgz, .tar.gz ,zip ,gz, .tar文件

    转载:https://blog.csdn.net/fu6543210/article/details/7984578 将.tgz文件解压在当前目录: tar zxvf MY_NAME.tgz 将.ta ...

  9. 大型DELETE(删除大量数据)的一种解决方案

    通过执行单条DELETE语句来删除一个大型的数据集会有以下的缺点: 1.DELETE语句的操作要被完整地记录到日志中,这要求在事务日志中要有足够的空间以完成整个事务: 2.在删除操作期间(可能会花费很 ...

  10. 『学了就忘』Linux基础 — 16、Linux系统与Windows系统的不同

    目录 1.Linux严格区分大小写 2.Linux一切皆文件 3.Linux不靠扩展名区分文件类型 4.Linux中所有的存储设备都必须在挂载之后才能使用 5.Windows下的程序不能直接在Linu ...