又是毕业季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的题啊,一般有四种思路
直接硬算(极少用),考虑贡献, 或者利用公约数一定是最大公约数的约数(如本题,或者数论容斥),欧拉反演