LibreOJ #528. 「LibreOJ β Round #4」求和

二次联通门 : LibreOJ #528. 「LibreOJ β Round #4」求和

/*
    LibreOJ #528. 「LibreOJ β Round #4」求和
    
    题目要求的是有多少对数满足他们的最大公约数的质因子不超过一个
    f (x) 表示有多少对数满足最大公约数中含有x^2这个因子
    那么f (x) = N / x ^ 2 * M * (x ^ 2)
    答案即为所有数字减去不符合要求的数字个数

    但是我们发现,可能某对数字的最大公约数含有多个质数平方因子
    那么在处理的时候就会重复筛去

    这时我们可以用容斥原理,用μ来作为容斥系数
    枚举x即可
*/
#include <cstdio>
#include <iostream>
#include <cmath>

#define Max 3231231
inline long long min (long long a, long long b) { return a < b ? a : b; }
int mu[Max | 1], is[Max | 1], p[Max | 1];
#define Mod 998244353

int Main ()
{
    long long N, M; scanf ("%lld%lld", &N, &M); register int i, j;
    int Answer = 0; int C = 0;
    int Limit = min (sqrt (N), sqrt (M));
    for (i = 2, is[1] = true, mu[1] = 1; i <= Max; ++ i)
    {
        if (!is[i]) p[++ C] = i, mu[i] = -1;
        for (j = 1; j <= C && i * p[j] <= Max; ++ j)
        {
            is[i * p[j]] = true; if (i % p[j] == 0) break;
            mu[i * p[j]] = -mu[i];    
        }
    }
    for (i = 1; i <= Limit; ++ i)
        Answer = (Answer + mu[i] * (N / (1LL * i * i) % Mod) * (M / (1LL * i * i) % Mod) % Mod + Mod) % Mod;
    printf ("%d", Answer);
    return 0;
}
int ZlycerQan = Main ();
int main (int argc, char *argv[]) {;}
原文地址:https://www.cnblogs.com/ZlycerQan/p/7470078.html