zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 162 E

    题目描述

    一个长度为 (n) 的序列 ({A_1, A_2, ..., A_n}), 其中每一位 (A_i) 取值为 ([1, k]).
    共有 (k^n) 种序列, 求所有序列的 (gcd(A_1, A_2, ..., A_n)) 的和.
    (( 2 le n le 10^5, 1 le k le 10^5))

    Solution

    (ans = sumlimits_{A_1 = 1}^ksumlimits_{A_2 = 1}^k...sumlimits_{A_n = 1}^kgcd(A_1, A_2, ..., A_n))
    (= sumlimits_{t = 1}^ktsumlimits_{A_1 = 1}^ksumlimits_{A_2 = 1}^k...sumlimits_{A_n = 1}^k[gcd(A_1, A_2, ..., A_n) = t])
    (= sumlimits_{t = 1}^ktsumlimits_{A_1 = 1}^{lfloordfrac{k}{t} floor}sumlimits_{A_2 = 1}^{lfloordfrac{k}{t} floor}...sumlimits_{A_n = 1}^{lfloordfrac{k}{t} floor}[gcd(A_1, A_2, ..., A_n) = 1])
    (= sumlimits_{t = 1}^ktsumlimits_{A_1 = 1}^{lfloordfrac{k}{t} floor}sumlimits_{A_2 = 1}^{lfloordfrac{k}{t} floor}...sumlimits_{A_n = 1}^{lfloordfrac{k}{t} floor}sumlimits_{d|gcd(A_1, A_2, ..., A_n)}mu(d))
    (= sumlimits_{t=1}^ktsumlimits_{d=1}^{lfloordfrac{k}{t} floor} mu(d) {lfloordfrac{lfloordfrac{k}{t} floor}{d} floor}^n)
    (= sumlimits_{t=1}^ktsumlimits_{d=1}^{lfloordfrac{k}{t} floor} mu(d) {lfloordfrac{k}{td} floor}^n)
    ({lfloordfrac{k}{td} floor})({lfloordfrac{k}{t} floor}) 都可以分块, 复杂度 (O(n))

    Code

    int n, k;
    int primes[N], cnt, mu[N], sum[N];
    bool st[N];
    
    void e_prime()
    {
    	mu[1] = 1;
    	for(int i = 2; i < N; ++ i)
    	{
    		if(!st[i]) 
    		{
    			primes[cnt ++] = i;
    			mu[i] = -1;
    		}
    		for(int j = 0; i * primes[j] < N; ++ j)
    		{
    			st[primes[j] * i] = 1;
    			if(i % primes[j] == 0) break;
    			mu[i * primes[j]] = -mu[i]; 
    		}
    	}
    	for(int i = 1; i < N; ++ i) sum[i] = sum[i - 1] + mu[i];
    }
    
    int g(int a, int x)
    {
    	return a / (a / x);
    }
    
    int q_pow(int a, int b)
    {
    	int res = 1;
    	while(b)
    	{
    		if(b & 1) res = (LL)res * a % P;
    		a = (LL)a * a % P;
    		b >>= 1;
    	}
    	return res;
    }
    
    int main()
    {
    	e_prime();
    	IOS; cin >> n >> k;
    	LL res = 0;
    	for(int p = 1, q; p <= k; p = q + 1)
    	{
    		q = min(k, g(k, p));
    		LL A = (LL)(p + q) * (q - p + 1) / 2 % P;
    		for(int l = 1, r; l <= k / p; l = r + 1)
    		{
    			r = min(k / p, g(k / p, l));
    			LL B = sum[r] - sum[l - 1];
    			LL C = q_pow((k / p) / l, n);
    			res = (res + A * B % P * C % P) % P; 
    		}
    	}
    	res = (res % P + P) % P;
    	cout << res << endl;
    	return 0;
    } 
    
  • 相关阅读:
    Python学习笔记Day24
    Python学习笔记Day23
    Python学习笔记Day22
    Python学习笔记Day21
    Python学习笔记Day19
    Python学习笔记Day18
    Python学习笔记Day17
    Python学习笔记Day16
    Python学习笔记Day15
    linux普通文件权限和系统目录权限的实践及结论
  • 原文地址:https://www.cnblogs.com/ooctober/p/14970150.html
Copyright © 2011-2022 走看看