又是毕业季II

考虑一个数可以作为多少个数的公约数

\(c[i]\)表示\(i\)是多少个数的公约数,那么对于当我们求\(k\)的时候,我们取\(c[i]≥k\)\(i\)的最大值作为答案就好了

这是因为:对所有\(c[i]<k\)\(i\)来说,不可能是答案,而对任意一个\(c[i]≥k\)\(i\)来说,我们删除\(i\)对应的\(c[i]\)个数中的一些数使剩下的数有\(k\)个,那么这\(k\)个数的最大公约数显然是\(i\)的倍数,由于我们取的是最大的\(i\),所以最大公约数就是\(i\)

代码实现:我们没有必要将所有\(i\)按照\(c[i]\)为关键字排序,而是可以借鉴这篇题解的代码(这确实比较神奇,不满足单调性却可以利用类似双指针的做法进行扫描,然而正确性是不难证明的)

总结一下这么多gcd的题啊,一般有四种思路

直接硬算(极少用),考虑贡献, 或者利用公约数一定是最大公约数的约数(如本题,或者数论容斥),欧拉反演

posted @ 2024-03-09 21:17  最爱丁珰  阅读(4)  评论(0编辑  收藏  举报