CF1554E You
考虑到删点操作的实质是指认边的方向。
由于这是一棵树,所以有很好的性质。
我们完全可以以此从树叶开始,往上拓扑进行,按照对某个数的取膜的大小来进行操作。
由此可知,除了 \(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的更多相关文章
- Involuting Bunny! (2021.8)
CF1555F & Submission. Tags:「A.生成树」「B.Tricks」 分类处理询问的 trick:连接两个连通块的边显然合法,先用这些边构建生成森林.发现每条边 ...
随机推荐
- [BUAA]起点 软工第一次作业-热身
项目 内容 这个作业属于哪个课程 2020计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 第一次作业-热身! 我在这个课程的目标是 了解软件开发,提高自己的工程能力和团队协作能力 这个作业在哪 ...
- 这一篇 K8S(Kubernetes)我觉得可以了解一下!!!
点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 什么是Kubernetes? Kubernetes 是Google开源的分布式容器管理平台,是为 ...
- 洛谷 P3232 [HNOI2013]游走
链接: P3232 题意: 和上次考试 T4 的简化且无修改一样,经典图上高斯消元求期望. 分析: 要求出每个点的期望出发次数 \(f_i\),每个点度数为 \(d_i\),有 \[f1=\sum\d ...
- Java并发:Condition接口
Condition 接口与 Lock 配合实现了等待 / 通知模式,这个和 Object 的监视器方法(wait.notify.notifyAll 等方法)一样,都是实现了等待 / 通知模式,但这两者 ...
- linux下文件后面带~
之前发现有时候在命令行ls会看到一些文件后面带有-,而这些文件的名字和我们文件夹中的某些文件是一模一样的文件,在文件夹中没发现就很大胆地删掉了也没是,一直没管,觉得是什么临时复制的文件或者隐藏文件.今 ...
- 如何反编译微信小程序👻
如何反编译微信小程序 准备工具: 夜神模拟器(或者你可以自己准备一个安卓模拟器,有root权限.) RE文件管理器(下载地址:https://soft.ucbug.com/uploads/shouji ...
- ☕【Java技术指南】「序列化系列」深入挖掘FST快速序列化压缩内存的利器的特性和原理
FST的概念和定义 FST序列化全称是Fast Serialization Tool,它是对Java序列化的替换实现.既然前文中提到Java序列化的两点严重不足,在FST中得到了较大的改善,FST的特 ...
- 折腾systemd-nspawn运行centos7
Archlinux创建Debian/Ubuntu的systemd-nspawn容器是很简单的,因为有debootstrap软件.某天我突然想装个centos7玩玩,搜了半天没发现有什么类似于deboo ...
- 快速排序--洛谷卡TLE后最终我还是选择了三向切割
写在前边 这篇文章呢,我们接着聊一下排序算法,我们之前已经谈到了简单插入排序 和ta的优化版希尔排序,这节我们要接触一个更"高级"的算法了--快速排序. 在做洛谷的时候,遇到了一道 ...
- Spring Boot 快速整合Swagger
一.前言 Spring Boot作为当前最为流行的Java web开发脚手架,越来越多的开发者选择用其来构建企业级的RESTFul API接口.这些接口不但会服务于传统的web端(b/s),也会服务于 ...