• luogu1891 疯狂lcm ??欧拉反演?


    link

    给定正整数N,求LCM(1,N)+LCM(2,N)+...+LCM(N,N)。

    多组询问,1≤T≤300000,1≤N≤1000000

    (sum_{i=1}^nlcm(i,n))

    (=sum_{i=1}^nfrac{in}{gcd(i,n)})

    (=nsum_{p|n}frac 1 psum_{i=1}^ni[gcd(i,n)=p])

    (=nsum_{p|n}sum_{i=1}^{n/p}i[gcd(i,frac n p)=1])//注意这里是n/p而不是n,mdzz第一次我这里推错了

    (=nsum_{p|n}sum_{i=1}^{p}i[gcd(i,p)=1])

    然后就可以套用公式(sum_{i=1}^ni[gcd(i,n)=1]=frac {[n=1]+nvarphi(n)}{2})

    (=nsum_{p|n}frac{[p=1]+pvarphi(p)}{2})

    线性筛,对于所有(p)预处理所有的([p=1]+varphi(p)*p)

    然后枚举倍数,在100Wlog100W时间复杂度内求出所有N的答案

    代码没时间写了,明天放

    然而还是在3分钟内写出了代码

    #include <cstdio>
    using namespace std;
    
    const int fuck = 1000000;
    bool vis[fuck + 10];
    int prime[fuck + 10], tot;
    int phi[fuck + 10];
    long long ans[fuck + 10];
    
    int main()
    {
    	phi[1] = 1;
    	for (int i = 2; i <= fuck; i++)
    	{
    		if (vis[i] == false) prime[++tot] = i, phi[i] = i - 1;
    		for (int j = 1; j <= tot && i * prime[j] <= fuck; j++)
    		{
    			vis[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] * (prime[j] - 1);
    		}
    	}
    	for (int p = 1; p <= fuck; p++)
    	{
    		long long sb = (p == 1) + phi[p] * (long long)p;
    		for (int b = p; b <= fuck; b += p)
    		{
    			ans[b] += sb;
    		}
    	}
    	int t; scanf("%d", &t);
    	while (t --> 0)
    	{
    		int x;
    		scanf("%d", &x);
    		printf("%lld
    ", ans[x] * x / 2);
    	}
    	return 0;
    }
    
  • 相关阅读:
    poj 2892 && 3468
    hdu 2444
    反素数
    poj 2406 && 1961
    Java定时器Timer的使用
    Linux环境下如何生成core文件
    Java异步CompletableFuture的使用
    Java中线程池的使用
    Linux系统添加应用服务进程的守护进程
    C++通过Webbrowser调用JavaScript
  • 原文地址:https://www.cnblogs.com/oier/p/10296361.html
Copyright © 2020-2023  润新知