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:连接两个连通块的边显然合法,先用这些边构建生成森林.发现每条边 ...
随机推荐
- Mybatis 一对多延迟加载,并且子查询中与主表字段不对应 (19)
Mybatis 一对多延迟加载,并且子查询中与主表字段不对应应用说明. 实现一对多关联(懒加载),一个教研组对应多个教师,既:教师的教研编号与教研组的教研编号关联,并且教师关联教研组外键与教研组编号 ...
- JavaScript 数组 常用方法(二)
写在前面:续接上篇 JavaScript 数组 常用方法 数组常用方法第二弹来了: some && every 描述: every()与some()方法都是JS中数组的迭代方法. so ...
- CentOS 文件管理
目录 目录管理 目录结构 切换目录 查看目录 创建目录 复制目录 剪切目录 删除目录 文件管理 查看文件 创建文件 复制文件 剪切文件 删除文件 创建链接 目录管理 目录也是一种文件. 蓝色目录,绿色 ...
- Java:ConcurrentHashMap类小记-1(概述)
Java:ConcurrentHashMap类小记-1(概述) 对 Java 中的 ConcurrentHashMap类,做一个微不足道的小小小小记,分三篇博客: Java:ConcurrentHas ...
- Redis:学习笔记-01
Redis:学习笔记-01 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 1. Redis入门 2.1 ...
- Python网络爬虫实战入门
一.网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序. 爬虫的基本流程: 发起请求: 通过HTTP库向目标站点发起请求,也就是发送一个Request ...
- poj 2311 Cutting Game (SG)
题意: 有一张W*H的纸片. 每人每次可以横着撕或者竖着撕,先撕出1*1那一方胜. 数据范围: W and H (2 <= W, H <= 200) 思路: 很好抽象出游戏图的模型,用SG ...
- zabbix 自定义监控项,监控tomcat访问量
uv:访客量.每个独立上网电脑视为一位访客.pv:访问量.页面浏览量或者点击量,访客每访问一次记录一次. 1.创建文件 /home/zabbix/pvuv_number.sh [ #/bin/bash ...
- Effective java 读书笔记(2)
第四条:通过私有构造器强化不可实例化的能力 有时可能需要编写只包含静态方法和静态域的类,这样的工具类不希望被实例化,因为实例化对它来说没有意义. 然而,在缺少显式构造器的情况下,系统会自动提供一个缺省 ...
- Qt 使用大神插件快速创建树状导航栏
前言 本博客仅仅记录自己的采坑过程以及帮助网友避坑,方便以后快速使用自定义控件,避免重复出错. 下载插件 大神 Github Qt 自定义控件项目地址:https://github.com/feiya ...