zoukankan      html  css  js  c++  java
  • BZOJ 2226 LCMSum

    Description

    Given (n), calculate the sum (LCM(1,n) + LCM(2,n) + cdots + LCM(n,n)), where (LCM(i,n)) denotes the Least Common Multiple of the integers (i) and (n).

    Input

    The first line contains (T) the number of test cases. Each of the next (T) lines contain an integer (n).

    Output

    Output (T) lines, one for each test case, containing the required sum.

    Sample Input

    3
    1
    2
    5

    Sample Output

    1
    4
    55

    HINT

    (1 le T le 300000)
    (1 le n le 1000000)

    题目求$$sum_{i=1}^{n}LCM(i,n)$$
    根据(LCM)的公式,即$$sum_{i=1}^{n}frac{i imes n}{GCD(i,n)}$$
    我们枚举(GCD)——(g),即$$sum_{g=1}^{n}[g mid n]n sum_{i=1}^{n}i[GCD(i,n)=g]$$
    化简一下,转而求$$sum_{g=1}^{n}[g mid n]n sum_{i=1}^{n}i[GCD(frac{i}{g},frac{n}{g})=1]$$
    变化一下(i)的范围:$$sum_{g=1}^{n}[g mid n]n sum_{i=1}^{frac{n}{g}}i[GCD(i,frac{n}{g})=1]$$
    (sum_{i=1}^{frac{n}{g}}i[GCD(i,frac{n}{g})=1])(frac{n}{g})内与之互质的数的和,这个有个公式:$$sum_{i=1}^{n}i[GCD(n,i)=1]= frac{phi(n) imes n}{2}$$
    如何证明,假设某个数(a)(n)互质,那么(n-a)一定也与(n)互质,这样的数一共有(phi(n))个,于是得证,但在(n=1)是要特判,于是这个式子就出来了。$$sum_{i=1}{n}LCM(i,n)=sum_{g=1}{n}[g mid n]n frac{phi(frac{n}{g}) imes frac{n}{g} }{2}$$

    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    typedef long long ll;
    #define maxn (1000010)
    bool exist[maxn]; int n,phi[maxn],prime[maxn],tot;
    
    inline void ready()
    {
    	phi[1] = 1;
    	for (int i = 2;i < maxn;++i)
    	{
    		if (!exist[i]) phi[i] = i-1,prime[++tot] = i;
    		for (int j = 1;j <= tot;++j)
    		{
    			if (i*prime[j] >= maxn) break;
    			exist[i*prime[j]] = true;
    			if (i % prime[j] == 0) { phi[i*prime[j]] = phi[i]*prime[j]; break; }
    			else phi[i*prime[j]] = phi[i]*phi[prime[j]];
    		}
    	}
    }
    inline ll calc(int g)
    {
    	if (g == 1) return 1;
    	return ((ll)phi[g]*(ll)g>>1);
    }
    
    int main()
    {
    	freopen("2226.in","r",stdin);
    	freopen("2226.out","w",stdout);
    	ready();
    	int T; scanf("%d",&T);
    	while (T--)
    	{
    		scanf("%d",&n);
    		ll ans = 0;
    		for (int g = 1;g * g <= n;++g)
    			if (n % g == 0)
    			{
    				ans += (ll)n*calc(n / g);
    				if (g * g != n) ans += (ll)n*calc(g);
    			}
    		printf("%lld
    ",ans);
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    【HDOJ6666】Quailty and CCPC(模拟)
    【2019 Multi-University Training Contest 8】
    分布式锁的理解
    反射工具类【ReflectionUtils】
    Maven常用命令
    maven常用命令介绍
    mysql 优化策略(如何利用好索引)
    centos7搭建svn服务器及客户端设置
    Centos7 配置subversion
    Centos7更改网卡名称Eth0
  • 原文地址:https://www.cnblogs.com/mmlz/p/4394723.html
Copyright © 2011-2022 走看看