[HDU6833]A Very Easy Math Problem

题意


a 1 = 1 n a 2 = 1 n a x = 1 n ( j = 1 x a j k ) f ( gcd ( a 1 , a 2 , . . . , a x ) ) gcd ( a 1 , a 2 , . . . , a x ) m o d    1 0 9 + 7 \sum_{a_1=1}^n\sum_{a_2=1}^n\cdots\sum_{a_x=1}^n\Big(\prod_{j=1}^xa_j^k\Big)f(\gcd(a_1,a_2,...,a_x))\cdot\gcd(a_1,a_2,...,a_x)\mod 10^9+7

若存在 k > 1 k>1 ,且 k 2 x k^2\mid x ,则 f ( x ) = 0 f(x)=0 ;否则 f ( x ) = 1 f(x)=1

1 n 2 × 1 0 5 , 1 k , x 1 0 9 1\le n\le2\times10^5,1\le k,x\le10^9


题解

首先 f ( x ) = μ ( x ) f(x)=|\mu(x)| ;其次根据乘法分配律,有
g ( n ) = a 1 = 1 n a 2 = 1 n a x = 1 n ( j = 1 x a j k ) = a 1 = 1 n a 1 k a 2 = 1 n a 2 k a x = 1 n a x k = ( i = 1 n i k ) x \begin{aligned} g(n)\overset{\text{令}}{=}&\sum_{a_1=1}^n\sum_{a_2=1}^n\cdots\sum_{a_x=1}^n\Big(\prod_{j=1}^xa_j^k\Big)\\ =&\sum_{a_1=1}^na_1^k\sum_{a_2=1}^na_2^k\cdots\sum_{a_x=1}^na_x^k\\ =&\Big(\sum_{i=1}^ni^k\Big)^x \end{aligned}
枚举 gcd \gcd 化简原式
a 1 = 1 n a 2 = 1 n a x = 1 n ( j = 1 x a j k ) f ( gcd ( a 1 , a 2 , . . . , a x ) ) gcd ( a 1 , a 2 , . . . , a x ) = d = 1 n μ ( d ) d a 1 = 1 n a 2 = 1 n a x = 1 n ( j = 1 x a j k ) [ gcd ( a 1 , a 2 , . . . , a x ) = d ] = d = 1 n μ ( d ) d k x + 1 b 1 = 1 n d b 2 = 1 n d b x = 1 n d ( j = 1 x b j k ) [ gcd ( b 1 , b 2 , . . . , b x ) = 1 ] b i = a i d = d = 1 n μ ( d ) d k x + 1 b 1 = 1 n d b 2 = 1 n d b x = 1 n d ( j = 1 x b j k ) p gcd μ ( p ) = d = 1 n μ ( d ) d k x + 1 p = 1 n d μ ( p ) p k x c 1 = 1 n p d c 2 = 1 n p d c x = 1 n p d ( j = 1 x c j k ) c i = b i p = d = 1 n μ ( d ) d k x + 1 p = 1 n d μ ( p ) p k x g ( n p d ) = T = 1 n g ( n T ) d T μ ( d ) d k x + 1 μ ( T d ) ( T d ) k x T = p d = T = 1 n g ( n T ) T k x d T μ ( d ) μ ( T d ) d \begin{aligned} &\sum_{a_1=1}^n\sum_{a_2=1}^n\cdots\sum_{a_x=1}^n\Big(\prod_{j=1}^xa_j^k\Big)f(\gcd(a_1,a_2,...,a_x))\cdot\gcd(a_1,a_2,...,a_x)\\ =&\sum_{d=1}^n|\mu(d)|d\sum_{a_1=1}^n\sum_{a_2=1}^n\cdots\sum_{a_x=1}^n\Big(\prod_{j=1}^xa_j^k\Big)[\gcd(a_1,a_2,...,a_x)=d]\\ =&\sum_{d=1}^n|\mu(d)|d^{kx+1}\sum_{b_1=1}^{\lfloor\frac nd\rfloor}\sum_{b_2=1}^{\lfloor\frac nd\rfloor}\cdots\sum_{b_x=1}^{\lfloor\frac nd\rfloor}\Big(\prod_{j=1}^xb_j^k\Big)[\gcd(b_1,b_2,...,b_x)=1]&b_i=\lfloor\frac{a_i}d\rfloor\\ =&\sum_{d=1}^n|\mu(d)|d^{kx+1}\sum_{b_1=1}^{\lfloor\frac nd\rfloor}\sum_{b_2=1}^{\lfloor\frac nd\rfloor}\cdots\sum_{b_x=1}^{\lfloor\frac nd\rfloor}\Big(\prod_{j=1}^xb_j^k\Big)\sum_{p\mid\gcd}\mu(p)\\ =&\sum_{d=1}^n|\mu(d)|d^{kx+1}\sum_{p=1}^{\lfloor\frac nd\rfloor}\mu(p)p^{kx}\sum_{c_1=1}^{\lfloor\frac n{pd}\rfloor}\sum_{c_2=1}^{\lfloor\frac n{pd}\rfloor}\cdots\sum_{c_x=1}^{\lfloor\frac n{pd}\rfloor}\Big(\prod_{j=1}^xc_j^k\Big)&c_i=\lfloor\frac{b_i}p\rfloor\\ =&\sum_{d=1}^n|\mu(d)|d^{kx+1}\sum_{p=1}^{\lfloor\frac nd\rfloor}\mu(p)p^{kx}g(\lfloor\frac n{pd}\rfloor)\\ =&\sum_{T=1}^ng(\lfloor\frac nT\rfloor)\sum_{d|T}|\mu(d)|d^{kx+1}\mu(\frac Td)(\frac Td)^{kx}&T=pd\\ =&\sum_{T=1}^ng(\lfloor\frac nT\rfloor)T^{kx}\sum_{d|T}|\mu(d)|\mu(\frac Td)d\\ \end{aligned}

h ( T ) = T k x d T μ ( d ) μ ( T d ) d \displaystyle h(T)=T^{kx}\sum_{d|T}|\mu(d)|\mu(\frac Td)d ,用枚举倍数的方法、降幂公式和快速幂就可以在 O ( n log n + n log P ) O(n\log n+n\log P) 的时间内求出所有的 h ( T ) h(T)

S ( n ) = T = 1 n g ( n T ) h ( T ) \displaystyle S(n)=\sum_{T=1}^ng(\lfloor\frac nT\rfloor)h(T) ,到这里已经可以利用数论分块在 O ( n log n P + T n ) O(n\log nP+T\sqrt n) 的时间内解决这道题了,但是还可以优化。

考虑如何快速求出所有的 S ( n ) S(n)

注意到对于 i j n < ( i + 1 ) j ij\le n<(i+1)j 的所有 n n ,都含有 g ( i ) h ( j ) g(i)h(j) 这一项,所以可以枚举 i , j i,j ,转化为对 S ( n ) S(n) 进行区间加法,差分后求前缀和即可,时间复杂度 O ( i = 1 n j = 1 n i 1 ) = O ( n log n ) \displaystyle O(\sum_{i=1}^n\sum_{j=1}^{\lfloor\frac ni\rfloor}1)=O(n\log n)

总时间复杂度 O ( n log n + n log P + T ) O(n\log n+n\log P+T)

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, P = 1e9 + 7;
typedef long long ll;
int n = 2e5, k, x;
int is[N], pr[N], mu[N], g[N], h[N], S[N];
inline int FastExp(int a, int b) {
    int x = 1;
    for (; b; b >>= 1, a = (ll)a * a % P)
        if (b & 1)
            x = (ll)x * a % P;
    return x;
}
int main() {
    scanf("%*d%d%d", &k, &x);
    mu[1] = 1;
    for (int i = 2; i <= n; ++i) {
        if (!is[i])
            pr[++pr[0]] = i, mu[i] = -1;
        for (int j = 1, x; j <= pr[0] && (x = i * pr[j]) <= n; ++j) {
            is[x] = 1, mu[x] = -mu[i];
            if (!(i % pr[j])) {
                mu[x] = 0;
                break;
            }
        }
    }
    for (int i = 1; i <= n; ++i)
        g[i] = (g[i - 1] + FastExp(i, k)) % P;
    for (int i = 1; i <= n; ++i)
        g[i] = FastExp(g[i], x);
    for (int i = 1; i <= n; ++i)
        for (int j = i; j <= n; j += i)
            mu[i] ? h[j] = (h[j] + mu[j / i] * i + P) % P : 0;
    for (int i = 1; i <= n; ++i)
        h[i] = (ll)h[i] * FastExp(i, (ll)k * x % (P - 1)) % P;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; i * j <= n; ++j) {
            int m = i * j;
            S[m] = (S[m] + (ll)g[i] * h[j] % P) % P;
            if (m + j <= n)
                S[m + j] = (S[m + j] - (ll)g[i] * h[j] % P + P) % P;
        }
    for (int i = 1; i <= n; ++i)
        S[i] = (S[i] + S[i - 1]) % P;
    while (~scanf("%d", &n))
        printf("%d\n", S[n]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/BeNoble_/article/details/107851650