2020杭电多校第六场 A Very Easy Math Problem 莫比乌斯反演 (HDU 6833)

A Very Easy Math Problem

题解

∑ a 1 = 1 n ∑ a 2 = 1 n ⋅ ⋅ ⋅ ∑ a x = 1 n ( ∏ j = 1 x a j k ) f ( g c d ( a 1 , a 2 , . . . , a n ) ) g c d ( a 1 , a 2 , . . . , a n ) = ∑ d = 1 n d f ( d ) ∑ a 1 = 1 n ∑ a 2 = 1 n ⋅ ⋅ ⋅ ∑ a x = 1 n ( ∏ j = 1 x a j k ) [ g c d ( a 1 , a 2 , . . . , a n ) = d ] = ∑ d = 1 n d k x + 1 f ( d ) ∑ a 1 = 1 ⌊ n / d ⌋ ∑ a 2 = 1 ⌊ n / d ⌋ ⋅ ⋅ ⋅ ∑ a x = 1 ⌊ n / d ⌋ ( ∏ j = 1 x a j k ) ∑ t ∣ a 1 , t ∣ a 2 , . . . , t ∣ a n μ ( t ) = ∑ d = 1 n d k x + 1 f ( d ) ∑ a 1 = 1 ⌊ n / d ⌋ a 1 k ∑ a 2 = 1 ⌊ n / d ⌋ a 2 k ⋅ ⋅ ⋅ ∑ a x = 1 ⌊ n / d ⌋ a x k ∑ t ∣ a 1 , t ∣ a 2 , . . . , t ∣ a n μ ( t ) = ∑ d = 1 n d k x + 1 f ( d ) ( ∑ i = 1 ⌊ n / d ⌋ i k ) x ∑ t ∣ a 1 , t ∣ a 2 , . . . , t ∣ a n μ ( t ) = ∑ d = 1 n d k x + 1 f ( d ) ∑ t = 1 ⌊ n / d ⌋ μ ( t ) ( ∑ i = 1 ⌊ n / d t ⌋ ( i t ) k ) x = ∑ d = 1 n d k x + 1 f ( d ) ∑ t = 1 ⌊ n / d ⌋ μ ( t ) t k x ( ∑ i = 1 ⌊ n / d t ⌋ i k ) x T = d t → = ∑ T = 1 n ( ∑ i = 1 ⌊ n / T ⌋ i k ) x T k x ∑ d ∣ T f ( d ) μ ( T d ) d 令 g ( T ) = ∑ d ∣ T f ( d ) μ ( T d ) d → = ∑ T = 1 n ( ∑ i = 1 ⌊ n / T ⌋ i k ) x T k x g ( T ) \begin{aligned} & \displaystyle\sum_{a_1=1}^{n} \displaystyle\sum_{a_2=1}^{n}···\displaystyle\sum_{a_x=1}^{n} \left(\prod_{j = 1} ^ {x} a_j ^ k \right) f \left( gcd(a_1, a_2, ...,a_n) \right) gcd(a_1, a_2, ...,a_n) \\ & =\displaystyle\sum_{d = 1} ^ {n} d f(d) \displaystyle\sum_{a_1=1}^{n} \displaystyle\sum_{a_2=1}^{n}···\displaystyle\sum_{a_x=1}^{n} \left(\prod_{j = 1} ^ {x} a_j ^ k \right) \left[gcd(a_1, a_2, ...,a_n) = d \right] \\ & = \displaystyle\sum_{d = 1} ^ {n} d ^ {kx+1} f(d) \displaystyle\sum_{a_1=1}^{\lfloor n/d \rfloor} \displaystyle\sum_{a_2=1}^{\lfloor n/d \rfloor}···\displaystyle\sum_{a_x=1}^{\lfloor n/d \rfloor} \left(\prod_{j = 1} ^ {x} a_j ^ k \right) \displaystyle\sum_{t|a_1,t|a_2,...,t|a_n} \mu(t) \\ & = \displaystyle\sum_{d = 1} ^ {n} d ^ {kx+1} f(d) \displaystyle\sum_{a_1=1}^{\lfloor n/d \rfloor} a_1^k \displaystyle\sum_{a_2=1}^{\lfloor n/d \rfloor} a_2^k ···\displaystyle\sum_{a_x=1}^{\lfloor n/d \rfloor} a_x^k \displaystyle\sum_{t|a_1,t|a_2,...,t|a_n} \mu(t) \\ & = \displaystyle\sum_{d = 1} ^ {n} d ^ {kx+1} f(d) \left( \displaystyle\sum_{i=1}^{\lfloor n/d \rfloor} i^k \right) ^ x \displaystyle\sum_{t|a_1,t|a_2,...,t|a_n} \mu(t) \\ & = \displaystyle\sum_{d = 1} ^ {n} d ^ {kx+1} f(d) \displaystyle\sum_{t = 1} ^ {\lfloor n/d \rfloor} \mu(t) \left( \displaystyle\sum_{i=1}^{\lfloor n/dt \rfloor} (it)^k \right) ^ x \\ & = \displaystyle\sum_{d = 1} ^ {n} d ^ {kx+1} f(d) \displaystyle\sum_{t = 1} ^ {\lfloor n/d \rfloor} \mu(t)t^{kx} \left( \displaystyle\sum_{i=1}^{\lfloor n/dt \rfloor} i^k \right) ^ x \\ T = dt \to & = \displaystyle\sum_{T = 1} ^ {n} \left( \displaystyle\sum_{i=1}^{\lfloor n/T \rfloor} i^k \right) ^ x T ^ {kx}\displaystyle\sum_{d|T} f(d) \mu(\frac{T}{d})d \\ 令g(T) = \displaystyle\sum_{d|T} f(d) \mu(\frac{T}{d})d \to & = \displaystyle\sum_{T = 1} ^ {n} \left( \displaystyle\sum_{i=1}^{\lfloor n/T \rfloor} i^k \right) ^ x T ^ {kx}g(T) \end{aligned} T=dtg(T)=dTf(d)μ(dT)da1=1na2=1nax=1n(j=1xajk)f(gcd(a1,a2,...,an))gcd(a1,a2,...,an)=d=1ndf(d)a1=1na2=1nax=1n(j=1xajk)[gcd(a1,a2,...,an)=d]=d=1ndkx+1f(d)a1=1n/da2=1n/dax=1n/d(j=1xajk)ta1,ta2,...,tanμ(t)=d=1ndkx+1f(d)a1=1n/da1ka2=1n/da2kax=1n/daxkta1,ta2,...,tanμ(t)=d=1ndkx+1f(d)i=1n/dikxta1,ta2,...,tanμ(t)=d=1ndkx+1f(d)t=1n/dμ(t)i=1n/dt(it)kx=d=1ndkx+1f(d)t=1n/dμ(t)tkxi=1n/dtikx=T=1ni=1n/TikxTkxdTf(d)μ(dT)d=T=1ni=1n/TikxTkxg(T)
这里 f f f函数可以 O ( n l o g n ) O(nlog n) O(nlogn)筛,筛完后 O ( n l o g n ) O(nlog n) O(nlogn) g g g函数,再对 g g g函数做一个前缀和
∑ i = 1 ⌊ n / T ⌋ i k \displaystyle\sum_{i=1}^{\lfloor n/T \rfloor} i^k i=1n/Tik可以预处理前缀和
最后计算的时候分块计算,总体复杂度 O ( n l o g n + T n ) O(nlogn+T\sqrt n) O(nlogn+Tn ),T为询问次数

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
const ll mod = 1e9 + 7;

ll qpow(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}


ll T, k, x, n;
int vis[N], prime[N], num, mu[N];
ll g[N], f[N], sumG[N], sum[N];
void init(int siz) {
    f[1] = mu[1] = 1, num = 0;
    for (int i = 2; i <= siz; i++) {
        f[i] = 1;
        if (!vis[i]) prime[++num] = i, mu[i] = -1;
        for (int j = 1; j <= num && i * prime[j] <= siz; j++) {
            vis[i * prime[j]] = 1;
            if (i % prime[j] == 0) {
                mu[i * prime[j]] = 0;
                break;
            }
            else mu[i * prime[j]] = mu[i] * mu[prime[j]];
        }
    }
    for (int d = 2; d * d <= siz; d++) for (int i = d * d; i <= siz; i += d * d) f[i] = 0;//f函数
    for (int d = 1; d <= siz; d++)
        for (int i = d; i <= siz; i += d)
            g[i] = (g[i] + 1ll * d * f[d] % mod * mu[i / d] % mod + mod) % mod;//g函数
    for (int i = 1; i <= siz; i++) {
        ll t = qpow(i, k);
        sum[i] = (sum[i - 1] + t) % mod;//i^k前缀和
        sumG[i] = (sumG[i - 1] + qpow(t, x) * g[i] % mod) % mod;//g函数前缀和
    }
}


int main() {

    scanf("%lld%lld%lld", &T, &k, &x);
    init(2e5);
    while (T--) {
        scanf("%lld", &n);
        ll ans = 0;
        for (int l = 1, r; l <= n; l = r + 1) {
            r = n / (n / l);
            ans = (ans + 1ll * (sumG[r] - sumG[l - 1] + mod) % mod * qpow(sum[n / l], x) % mod) % mod;
        }
        printf("%lld\n", (ans + mod) % mod);
    }



    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值