题目
求非空集合的数量,满足gcd=1,lcm=m(m<=1e18),答案取模998244353
思路来源
稲葉廻群、b站绿导师原谅你了容斥视频等
Grand Prix of Gomel (ITMO Day 5) - EOJ Wiki
题解1
先pollard_pho找因子,
然后f_x 表示 gcd=1, lcm=x 的组个数
我们仅计算 m 的因子的 f,那么考虑知道 x 所有真因子的时候怎么计算 f_m
首先直接要求每个元素都是 m 的因子,有 2^d(m) 种方案
然后考虑容斥掉,就是这里面会出现 gcd=x, lcm=y 的集合,且 (x,y)!=(1,m)
那么这种集合的数量恰好等于 f_(y/x),也就是把 f_m 减去所有 d(m/i)*f(i) 应该就行了
(x,y)的数量是满足y/x=i,y|m 的个数,即 x|(m/i),也就是d(m/i)
题解2

这个题解写的略抽象,想了很久,没太懂对称是啥意思,后来才想明白
对于每个质因子p,我们要用全集,减掉gcd是pi的倍数的集合,也要减掉lcm不是pi^ai的集合
每个质因子有两个集合,1e18最多有15个不同质因子,最多有30个集合,暴力枚举是O(2^30)的
实际是因为,只考虑gcd是pi的倍数时,方案是,
而只考虑lcm不是pi^ai时,说明是pi^ai删了至少一个质因子pi,方案数也是
这俩是一样的集合,所以可以把这俩合并成一个集合,
用选了其中0个/选了其中1个/选了其中2个去做区分,
选了两个就除以p两次,就优化到O(3^15)了
代码1(O(d(n)^2,但常数略小)
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<queue>
#include<set>

最低0.47元/天 解锁文章
1458

被折叠的 条评论
为什么被折叠?



