CF1554E You

news/2025/7/9 10:39:28/文章来源:https://www.cnblogs.com/gmh77/p/18524273

题面


题解

注意a[u]是点u位置的a,不是每选一个点然后把非标记个数丢进vector里(

每选择一个点,相当于把相邻的非标记的边标为外向,最后一个点u的外向边个数就是a[u]

又观察发现每种边定向方案都可以构造(拓扑),所以一共有2^(n-1)种方案

设f[k]表示gcd=k,g[k]表示k|gcd,求出g之后反演一下


显然g[1]=2^(n-1);对于g[k>1],发现叶子必定内向,然后去掉叶子后的下一层唯一确定父亲边方向,如此类推得到方案唯一,因此可以O(n)判断一个g[k]是否存在

找到任意一个叶子的父亲,记为sp,则a[sp]必为son[sp]或son[sp]+1,即k|son[sp]或k|(son[sp]+1),因此check之前先判一下,这样要O(n)check的k就只有根号(其实是σ(n))个了

总复杂度\(O(n\sqrt n)\)


不用反演的话,gcd=k就先用k|gcd来求(唯一),最后求gcd判一下,多一个log

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (int a=b; a<=c; a++)
#define fd(a,b,c) for (int a=b; a>=c; a--)
#define add(a,b) a=((a)+(b))%mod
#define mod 998244353
#define ll long long
#define file
using namespace std;const int N=1e5+10;
int a[N*2][2],ls[N],len;
int p[N],miu[N],lenp;
bool bz[N];
vector<int> v;
int son[N],sum[N],fa[N],sp;
ll f[N],g[N];
int T,n;void init()
{int l=100000;miu[1]=1;fo(i,2,l){if (!bz[i])p[++lenp]=i,miu[i]=-1;fo(j,1,lenp)if (1ll*i*p[j]<=l){bz[i*p[j]]=1;miu[i*p[j]]=-miu[i];if (i%p[j]==0){miu[i*p[j]]=0;break;}}elsebreak;}
}
void New(int x,int y)
{++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;
}ll qpower(ll a,int b)
{ll ans=1;while (b){if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;
}void dfs(int Fa,int t)
{int i;fa[t]=Fa;for (i=ls[t]; i; i=a[i][1])if (a[i][0]!=Fa){++son[t];dfs(t,a[i][0]);}v.push_back(t);if (sp==0 && son[t]) sp=t;
}int check(int k)
{if (!(son[sp]%k==0 || (son[sp]+1)%k==0)) return 0;memset(sum,0,(n+1)*4);fo(i,0,n-2){if (sum[v[i]]%k==0) ++sum[fa[v[i]]];elseif ((sum[v[i]]+1)%k!=0) return 0;}if (sum[1]%k==0) return 1;else return 0;
}void solve()
{scanf("%d",&n);len=0;sp=0;memset(ls,0,(n+1)*4);memset(f,0,(n+1)*8);memset(g,0,(n+1)*8);memset(son,0,(n+1)*4);memset(sum,0,(n+1)*4);fo(i,1,n-1){int x,y;scanf("%d%d",&x,&y);New(x,y),New(y,x);}if (n==2){f[1]=2;f[2]=0;}else{v.clear();dfs(0,1);g[1]=qpower(2,n-1);fo(k,2,n) g[k]=check(k);fo(i,1,n){for (int j=i; j<=n; j+=i)add(f[i],g[j]*miu[j/i]);}}fo(i,1,n) printf("%lld ",f[i]);printf("\n");
}int main()
{
//	freopen("CF1554E.in","r",stdin);init();scanf("%d",&T);for (;T;--T) solve();fclose(stdin);fclose(stdout);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/826421.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汽车虚拟仿真软件有哪些?行业软件大盘点!

汽车虚拟仿真可以大大提高汽车的研发效率和质量,降低成本和风险,增强汽车的竞争力和创新能力。本文将带领大家了解汽车虚拟仿真软件有哪些、汽车虚拟仿真实际应用以及汽车云交互实时渲染平台三个要点。汽车虚拟仿真是指利用计算机技术,根据汽车的设计、制造、测试、运行等各…

创建和销毁对象(一)

用静态工厂方法代替构造器 为了获得一个类的实例,可以使用公有构造器,也可以提供一个公有的静态工厂方法,他只是一个返回类的实例的静态方法public static Boolean valueOf(boolean b) { //Boolean是bool的一个Java装箱类return b ? Boolean.TRUE : Boolean.FALSE; } 静态…

《机器学习》 学习记录 - 第四章

第4章 决策树 4.1 基本流程 决策树(decision tree)是一类常见的机器学习方法,也叫“判定树”。顾名思义,决策树是基于树的结构进行决策的。 一般的,一棵决策树包含一个根结点、若干个内部结点和若干个叶结点:叶结点对应于决策结果,其他每个结点则对应于一个属性测试; 每…

11.2

List 接口的特点:List 是有序的集合,可以包含重复元素。它继承自 Collection 接口,提供了根据索引访问元素的方法。 流的定义:I/O 流是一种数据传输的通道,用于在程序和外部设备(如文件、网络等)之间传输数据。可以将流想象成水流,数据就像水流中的水滴。 字节流和字符…

11.3

流的分类:按数据流向分为输入流(从外部设备读取数据到程序)和输出流(从程序向外部设备写入数据);按功能分为节点流(直接连接到数据源或目的地的流)和处理流(对其他流进行包装,添加功能)。 缓冲流:缓冲流是一种处理流,它在内存中设置了一个缓冲区,可以提高 I/O 操…

「杂题乱刷2」CF2036G

这题 *2400 纯唐吧,感觉 *1800 差不多。 题目链接 CF2036G Library of Magic 解题思路 注:\(\oplus\) 表示异或运算。 首先我们想一个通解,就是先二分出第一个数和第三个数,然后第二个数就是所有数的异或和异或上这两个数,操作次数为 \(2 \times \log n + 1\),可以通过。…

进程间通信MPI

进程间通信MPI MPI(Message Passing Interface), 消息传递接口,通常用于并行计算场景中多进程间通信。以一个计算节点为例,节点中有8张GPU卡,通常一张卡上有一个训练任务进程,8张卡就会涉及到8个进程,此时训练时,进程间的通信就会变的极其重要。这种多进程通信,也被称为…

11.3每日总结

明天的正课准备自己的数据库连接情况,这次我提前一天晚上确保了我的idea和datagrip一切正常,上次的经历让我长了记性,而且锻炼了软件突发状况的心态,接下来我要进一步提高自己各种操作的熟练度,加油!