zoukankan      html  css  js  c++  java
  • [算进] POJ 2480(欧拉函数)

    Problem

    ACwing 题目地址

    POJ 题目地址

    Solution

    定理

    [sum_{i=1}^n gcd(i,n) = sum_{d|n} d*φ(frac{n}{d}) ]

    证明:

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

    [= sum_{d=1}^n sum_{i=1}^n [gcd(i,n) = d] * d ]

    [= sum_{d=1}^n d*sum_{i=1}^{lfloor frac{n}{d} floor} [gcd(i,lfloor frac{n}{d} floor) = 1] ]

    [= sum_{d=1}^n d*φ(lfloor frac{n}{d} floor) ]

    [= sum_{d|n} d*φ(frac{n}{d}) ]

    证毕。

    同样还有个小发现,右边这个式子是单位函数和欧拉函数的狄里克雷卷积,即 (id*φ)

    有了这个式子,我们就直接 (sqrt{n}) 枚举约数,然后分解质因数算欧拉函数。这样算的复杂度上限好像是 (O(n)) ?因为求欧拉函数分解质因数这里跑不满,所以是可以过的。

    Code

    Talk is cheap.Show me the code.

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    inline int read() {
    	int x=0,f=1; char ch=getchar();
    	while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    	while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    	return x * f;
    }
    int n,ans;
    int Phi(int n) {
        if(n == 1) return 1;
        int res = 1;
        for(int i=2;i<=sqrt(n);++i) {
            if(n % i == 0) {
                res *= (i-1); n /= i;
                while(n % i == 0) {
                    res *= i; n /= i;
                }
            }
        }
        if(n > 1) res *= (n-1);
        return res;
    }
    signed main()
    {
    	n = read();
    	int S = sqrt(n);
    	for(int i=1;i<=S;++i) {
    		if(n % i == 0) {
    			ans += i * Phi(n/i);
    			if(i*i != n) {
    				ans += (n/i) * Phi(i);
    			}
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    Summary

    这个定理很重要!!!

  • 相关阅读:
    (三)OpenCV-Python学习—图像平滑
    (二)OpenCV-Python学习—对比度增强
    (一)OpenCV-Python学习—基础知识
    mongodb的安装及使用
    python操作MySQL数据库的三个模块
    mysql数据库学习二
    (八)爬虫之js调试(登陆知乎)
    经典Paxos算法笔记
    ThreadPoolExecutor源码解读
    FutureTask源码解读
  • 原文地址:https://www.cnblogs.com/BaseAI/p/12292624.html
Copyright © 2011-2022 走看看