• 【18徐州网络赛D】Easy Math


    补充一点性质

    [sum_{d|n}varphi(d) = n ]

    证明

    对于 (n = 1) ,不难验证满足题意

    对于 (n = p^a) ,

    [sum_{d|n}varphi(d) = 1 + sum_{i = 1}^avarphi(p^i) \=p^a = n ]

    对于 (n = p_1^{a_1}...p_k^{a_k})

    [sum_{d|n}varphi(d) = sum_{i=0}^{a_1}varphi(p_1^i)sum_{i=0}^{a_2}varphi(p_2^i)...sum_{i=0}^{a_k}varphi(p_k^i)\=p_1^{a_1}...p_k^{a_k} = n ]

    • i % p == 0(varphi(i*p) = varphi(i) * p) , (p) 是质数

    D. Easy Math

    题意

    给定 (m,n)

    [sum_{i=1}^mmu(i * n) ]

    这样就可以进行递归了,但是我不会算复杂度...

    还注意到一个地方,线筛的判断 i % prime[j] == 0 的地方要注意函数的取值

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 1e6 + 10;
    typedef long long ll;
    ll prime[N], cnt, vis[N], mu[N], sum[N];
    
    
    void init() {
    	mu[1] = 1;
    	for (int i = 2; i < N; i++) {
    		if (!vis[i]) {
    			prime[++cnt] = i;
    			mu[i] = -1;
    		}
    		for (int j = 1; j <= cnt and prime[j] * i < N; j++) {
    			vis[prime[j] * i] = 1;
    			mu[prime[j] * i] = -mu[i];
    			if (i % prime[j] == 0) {
                    //**这一行不能去掉**
    				mu[i * prime[j]] = 0;
    				break;
    			}
    		}
    	}
    	for (int i = 1; i < N; i++) sum[i] = sum[i - 1] + mu[i];
    }
    
    ll n, m;
    unordered_map<ll, ll> M;
    ll djs(ll n) {
    	if (n < N) return sum[n];
    	if (M.count(n)) return M[n];
    	ll ans = 1;
    	for (ll l = 2, r; l <= n; l = r + 1) {
    		r = n / (n / l);
    		ans -= (r - l + 1) * djs(n / l);
    	}
    	return M[n] = ans;
    }
    ll cal(ll n) {
    	int ans = 1;
    	if (n < N) return mu[n];
    	for (ll i = 2; i * i <= n;i++) {
    		if (n % i == 0) {
    			if (n % (i * i) == 0)
    				return 0;
    			ans *= -1;
    			n /= i;
    		}
    	}
    	if (n > 1)
    		ans *= -1;
    	return ans;
    }
    ll solve(ll m, ll n) {
    	if (n == 1) return djs(m);
    
    	ll v = cal(n);
    	if (v == 0) return 0;
    
    	ll ans = 0;
    	ll t = m < sqrt(n) ? m : sqrt(n);
    	for (ll d = 1; d <= t; d++) {
    		if (n % d == 0) {
    			ans += cal(d) * solve(m / d, d);
    			if (n / d <= m)
    				ans += cal(n / d) * solve(m / (n / d), n / d);
    		}
    	}
    	return v * ans;
    }
    int main() {
    	init();
    	scanf("%lld%lld", &m, &n);
    	printf("%lld
    ", solve(m, n));
    }
    
  • 相关阅读:
    免费证书Let’s Encrypt
    kubernetes中使用ServiceAccount创建kubectl config 文件
    kubectl alias auto complete
    kubernetes dashboard permission errors
    du 与df 统计系统磁盘不一致原因与解决方法
    大访问量、高并发网站优化
    React的Sass配置
    转:Zepto的使用以及注意事项
    转: zepto的使用方法
    Extjs4 修改combox中store的数据
  • 原文地址:https://www.cnblogs.com/sduwh/p/14048419.html
Copyright © 2020-2023  润新知