zoukankan      html  css  js  c++  java
  • UVA11417 GCD

    题目地址

    题目链接

    题解

    先讨论任何没有限制的情况

    [large { egin{aligned} &sum_{i=1}^{n}sum_{j=1}^{n}gcd(i,j)\ &=sum_{k=1}^{n}ksum_{i=1}^{n}sum_{j=1}^{n}[gcd(i,j)=k]\ &=sum_{k=1}^{n}ksum_{i=1}^{lfloor frac{n}{k} floor }sum_{j=1}^{lfloor frac{n}{k} floor }[gcd(i,j)=1]\ &=sum_{k=1}^{n}ksum_{i=1}^{lfloor frac{n}{k} floor }sum_{j=1}^{lfloor frac{n}{k} floor }sum_{d|gcd(i,j)}mu(d)\ &=sum_{k=1}^{n}ksum_{d=1}^{n}{mu(d)lfloor frac{n}{kd} floor^2} end{aligned} } ]

    因为这个公式里面,我们对于所有的(i,j),同时也算了(j,i)

    显然gcd(i,j)=gcd(j,i)

    所以只需要除以2即可

    但是因为对于所有的(i,i)。我们只算了一次,因为这个在答案中不算进去,所以我们可以直接减掉再除以2

    所以最后的答案

    [large ANS= frac{sum_{k=1}^{n}ksum_{d=1}^{n}{mu(d)lfloor frac{n}{kd} floor^2}-sum_{i=1}^{n}i}{2} ]

    用容斥的思想来理解就很简单了

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define N 501
    int n;
    int vis[N], p[N], cnt = 0, mu[N], sum[N];
    
    void init() {
    	mu[1] = sum[1] = 1;
    	for(int i = 2; i < N; ++i) {
    		if(!vis[i]) {p[++cnt] = i; mu[i] = -1;}
    		for(int j = 1; j <= cnt && p[j] * i < N; ++j) {
    			vis[p[j] * i] = 1;
    			if(i % p[j] == 0) break;
    			mu[i * p[j]] -= mu[i];
    		}
    		sum[i] = sum[i - 1] + mu[i];
    	}
    }
    
    int calc(int m, int k) {
    	int ans = 0;
    	for(int l = 1, r; l <= m; l = r + 1) {
    		r = m / (m / l);
    		ans += (n / l / k) * (n / l / k) * (sum[r] - sum[l - 1]);
    	}
    	return ans;
    }
    
    int main() {
    	init();
    	while(scanf("%d", &n) == 1 && n) {
    		int ans = 0;
    		for(int i = 1; i <= n; ++i) {
    			ans += i * calc(n, i);
    		}
    		printf("%d
    ", (ans - (n * (n + 1)) / 2) / 2);
    	}
    	return 0;
    }
    
  • 相关阅读:
    【LeetCode】543. 二叉树的直径
    红色的眼睛黑色的心
    WinForm
    Windows地址栏的妙用
    C#
    WPF
    配置Notepad++万能调试
    盗取连接你wifi的人的qq
    Windows去除开始菜单图标背景
    解决Windows下文件无法删除的问题
  • 原文地址:https://www.cnblogs.com/henry-1202/p/10225760.html
Copyright © 2011-2022 走看看