2018.06.29 NOIP模拟 Gcd(容斥原理)

传送门

这是我做过的最可( d u du du)做( l i u liu liu)的 N O I P NOIP NOIP模拟级别的数论题。考场上打算写随机算法,想了想 30 30 30暴力更稳,于是交了暴力,结果 10 10 10分滚粗了。

这题让我们联想到正难则反的思想,题目上要我们求出所有可能解的方案数,那么我们这样想,我们先把总方案数求出来,显然是 n ∗ ( 2 n − 1 − 1 ) n*(2^{n-1}-1) n(2n11)

然后我们将不合法的情况去掉,我们设加入的数为 n u m b e r number number,那么我们要去掉的就是在加入 n u m b e r number number之前就已经使得 g c d gcd gcd 1 1 1的集合对应的 n u m b e r number number的选择方案数之和,以及在加入 n u m b e r number number之后 g c d gcd gcd仍然不为 1 1 1的方案数。这东西怎么算啊?变形代数式看看吧。

首先解决第二种情况,即在加入 n u m b e r number number之后 g c d gcd gcd仍然不为 1 1 1的方案数。这种情况直接统计所有集合中使得 g c d gcd gcd不为一的方案数即可,即用总方案数减去所有集合中使得 g c d gcd gcd 1 1 1的方案数。
另外,我们还知道,情况二其实是让我们求这个东西: ∑ ∣ S ∣ , g c d ( S ) ! = 1 ∣ S ∣ \sum_{|S|,gcd(S)!=1} |S| S,gcd(S)!=1S

这样的话,我们似乎将第二种情况转化成了第一种情况的子问题。怎么求出所有集合中使得 g c d gcd gcd 1 1 1的方案数呢?

考虑容斥原理,我们先将 g c d gcd gcd 1 1 1的倍数的集合数求出,减去 g c d gcd gcd 2 2 2的倍数的集合数……一直这样迭代下去,然后有个显然的结论,每个 g c d gcd gcd的容斥系数就对应着它们的莫比乌斯函数值。于是只需要提前用线性筛筛出所有数的莫比乌斯函数值,每次将情况二的答案加上 m u [ i ] ∗ ( 2 s u m [ i ] − 1 ) mu[i]*(2^{sum[i]}-1) mu[i](2sum[i]1)就行了,其中 s u m [ i ] sum[i] sum[i]表示所有数列中所有是 i i i的倍数的数的个数。

情况一?考虑用情况二反推情况一,再次将式子变形:我们要求的是在加入 n u m b e r number number之前就已经使得 g c d gcd gcd 1 1 1的集合对应的 n u m b e r number number的选择方案数之和,即 ∑ S , g c d ( S ) = = 1 ( n − ∣ S ∣ ) \sum_{S,gcd(S)==1} (n-|S|) S,gcd(S)==1(nS),显然这个式子可以展开成 ∑ S , ( g c d ) = = 1 1 − ∑ S , g c d ( S ) = = 1 ∣ S ∣ \sum_{S,(gcd)==1} 1-\sum_{S,gcd(S)==1} |S| S,(gcd)==11S,gcd(S)==1S,哇,后面一坨不是可以跟情况二合并吗?好像还可以抵掉一坨东西。最后发现只需要容斥计算乱搞一下就行了啊。

代码

你可能感兴趣的:(#,容斥原理,#,莫比乌斯函数,#,线性筛)