CR [gcd (i, j)]

https://www.luogu.org/record/22874213

Title effect: Given n and m, seeking Σ (1 <= i <= n) Σ (1 <= j <= m) GCD (i, j) * 2-1

f (x) = ΣΣ [gcd (i, j) == x]
then the answer is [Sigma] F (X) X, X: l-> // predetermined n-n <m, i.e. gcd (n, m) <= n
G (X) = [Sigma [X | GCD (I, J)] = n-/ X
m / X = F (X) + F (2x) + ... + F (n-/ X X)
I: X, 2x n-... / X
X, J: X, m ... 2x / X X. Therefore gcd (i, j) is a multiple of x are n-/ x m / x
transpose it, the pretreated with the original G [] operator f [], f (x) = g (x) - f (2x) - f (3x) - ... - f (the n-/ the X- the X-)
upside down and count f (x), then f (2x) ... f (the n-/ the X-
the X-) were all considered good

#include<cstdio>
#include<iostream>
using namespace std;
#define MAX 100000+999
#define ll long long

ll f[MAX];
int n,m;

int main() {
    scanf("%d%d",&n,&m);
    if(n > m) swap(n, m);
    for(int i = 1; i <= n; i++) f[i] = (ll)(n/i) * (m/i);// 注意加括号!!! 
    for(int i = n; i >= 1; i--) {//求f[i]
        for(int j = i+i; j <= n; j+=i) {
            f[i] -= f[j];
        }
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++) 
        ans += f[i]*i;
//  for(int i = 1; i <= n; i++) printf("%d\n",f[i]);
    printf("%lld",(ans<<1) - (ll)n*m);//把Σ变一下 
}

Guess you like

Origin www.cnblogs.com/tyner/p/11365983.html
gcd