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;
    }
    
  • 相关阅读:
    P4016 负载平衡问题 网络流
    P3357 最长k可重线段集问题 网络流
    mysql部署
    pve配置
    PVE手册资料
    PVE授权条款
    ovirt磁盘类型(IDE, virtio, virtio-scsi)
    oVirt-postgresql
    ovirt常用后台维护命令
    oVirt部署
  • 原文地址:https://www.cnblogs.com/mmlz/p/4394723.html
Copyright © 2011-2022 走看看