Petrozavodsk Programming Camp Winter 2018 Day 6: Grand Prix of Gomel K. Kids Aren‘t Alright(容斥好题)

题目

19313번: Kids Aren't Alright

求非空集合的数量,满足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的倍数时,方案是2^{d(m/p)}-1

而只考虑lcm不是pi^ai时,说明是pi^ai删了至少一个质因子pi,方案数也是2^{d(m/p)}-1

这俩是一样的集合,所以可以把这俩合并成一个集合,

用选了其中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>
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值