码迷,mamicode.com
首页 > 其他好文 > 详细

ΣΣ [ gcd(i,j) ]

时间:2019-08-16 20:47:02      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:scan   amp   define   efi   ++   include   org   wap   stream   

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

题目大意:给定n和m,求Σ(1<=i<=n)Σ(1<=j<=m)GCD(i,j)*2-1

f(x) = ΣΣ[ gcd(i,j)==x ]
那么答案即为 Σf(x)x, x:1->n //规定n<m, 即gcd(n,m)<=n
g(x) = Σ[ x | gcd(i,j) ] = n/x
m/x = f(x) + f(2x) + ... + f(n/x x)
i: x, 2x...n/x
x, j: x, 2x...m/x x。 所以gcd(i,j)为x倍数的有 n/x m/x
移项一下,用原先预处理好的g[]算f[], f(x) = g(x) - f(2x) - f(3x) - ... - f(n/xx)
倒过来算f(x),那么f(2x)...f(n/x
x)就都算好了

#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);//把Σ变一下 
}

ΣΣ [ gcd(i,j) ]

标签:scan   amp   define   efi   ++   include   org   wap   stream   

原文地址:https://www.cnblogs.com/tyner/p/11365983.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!