ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P6222 「P6156 简单题」加强版 题解

2021-12-16 20:05:33  阅读:185  来源: 互联网

标签:lfloor P6222 frac 加强版 题解 sum rfloor mu 2n


Description

Luogu传送门

Solution

加强版就只是纯粹的加强版,取模可以省掉,直接自然溢出即可,还是简单讲一讲吧。

首先,我们不难发现,\(f(x) = \mu^2(x)\)。

然后就是一波基础而不失难度的推式子。

\[\begin{aligned} & \sum\limits_{i = 1}^n\sum_{j = 1}^n(i + j)^k\mu^2(\gcd(i, j))\gcd(i, j) \\ =& \sum_{i = 1}^n\sum_{j = 1}^n(i + j)^k\sum_{d = 1}^n\mu^2(d)d[\gcd(i, j) = d] \\ =& \sum_{d = 1}^nd\mu^2(d)\sum_{i = 1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j = 1}^{\lfloor \frac{n}{d} \rfloor}(id + jd)^k[\gcd(i, j) = 1] \\ =& \sum_{d = 1}^nd^{k + 1}\mu^2(d)\sum_{i = 1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j = 1}^{\lfloor \frac{n}{d} \rfloor}(i + j)^k[\gcd(i, j) = 1] \\ =& \sum_{d = 1}^nd^{k + 1}\mu^2(d)\sum_{i = 1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j = 1}^{\lfloor \frac{n}{d} \rfloor}\sum_{p \mid (i, j)}\mu(p)(i + j)^k \\ =& \sum_{d = 1}^nd^{k + 1}\mu^2(d)\sum_{p = 1}^{\lfloor \frac nd \rfloor}\mu(p) \sum_{i = 1}^{\lfloor \frac{n}{dp} \rfloor}\sum_{j = 1}^{\lfloor \frac{n}{dp} \rfloor}\sum_{p \mid (i, j)}(ip + jp)^k \\ =& \sum_{d = 1}^nd^{k + 1}\mu^2(d)\sum_{p = 1}^{\lfloor \frac nd \rfloor}\mu(p)p^k \sum_{i = 1}^{\lfloor \frac{n}{dp} \rfloor}\sum_{j = 1}^{\lfloor \frac{n}{dp} \rfloor}\sum_{p \mid (i, j)}(i + j)^k \\ \end{aligned} \]

经典令 \(T = dp\),则:

\[\begin{aligned} & \sum_{T = 1}^n\sum_{i = 1}^{\lfloor \frac{n}{T} \rfloor}\sum_{j = 1}^{\lfloor \frac{n}{T} \rfloor}(i + j)^k\sum_{d | T}d^{k + 1}\mu^2(d)\mu(\frac Td)(\frac Td) ^k \\ =& \sum_{T = 1}^nT^k\sum_{i = 1}^{\lfloor \frac{n}{T} \rfloor}\sum_{j = 1}^{\lfloor \frac{n}{T} \rfloor}(i + j)^k\sum_{d \mid T}d\mu^2(d)\mu(\frac Td) \\ \end{aligned} \]

我们再令

\[S(n) = \sum\limits_{i = 1}^n\sum\limits_{j = 1}^n(i + j)^k \\ f(n) = \sum\limits_{d \mid n}d\mu^2(d)\mu(\frac nd) \]

那么原式为:

\[\sum_{T = 1}^nT^kS(\frac nT)f(T) \]

我们只要能够快速求出 \(S(n)\) 和 \(f(n)\) 即可。


先来看 \(S(n)\)。

设 \(F(n) = \sum\limits_{i = 1}^ni^k\),\(G(n) = \sum\limits_{i = 1}^nF(i)\)。

结论:

\[S(n) = G(2n) - 2G(n) \]

证明:

考虑使用数学归纳法。

\(S(n) = G(2n) - 2G(n)\),那么有 \(S(n + 1) = G(2n + 2) - 2G(n + 1)\)。

\[\begin{aligned} S(n + 1) = & \sum_{i = 1}^{n + 1}\sum_{j = 1}^{n + 1}(i + j)^k\\ =& S(n) + 2\sum_{i = 1}^n(i + n + 1)^k + (2n + 2)^k \\ =& S(n) + 2F(2n + 1) - 2F(n + 1) + F(2n + 2) - F(2n + 1) \\ =& G(2n) - 2G(n) + F(2n + 1) + F(2n + 2) - 2F(n + 1) \\ =& \sum_{i = 1}^{2n}F(i) - 2\sum_{i = 1}^nF(i) + F(2n + 1) + F(2n + 2) - 2F(n + 1) \\ =& G(2n + 2) - 2G(n + 1) \end{aligned} \]

证毕.

所以线性筛时筛出 \(i^k\) 求两遍前缀和得到 \(G(n)\),就可以 \(O(1)\) 求出 \(S(n)\) 了。


接下来看 \(f(n)\) 怎么求,\(f(n) = \sum\limits_{d \mid n}d\mu^2(d)\mu(\frac nd)\)。

我们发现 \(f(n)\) 是由好几个积性函数乘起来的,所以它也是积性函数。

对于质数 \(p\) :\(f(p) = \mu^2(1)\mu(p) \times p\mu^2(p)\mu(1) = p - 1\)

回忆一下线性筛的过程,我们对一个数 \(i\) 配上一个质数 \(p\)。

下面我们进行分类讨论:

  • \(p \nmid i\) :\(f(ip) = f(i) \times f(p)\)

  • \(p \mid i\) :

    • \(p^2 \mid i\) 且 \(p^3 \nmid i\) :

      \(f(p^2) = \mu^2(1)\mu(p^2) \times p\mu^2(p)\mu(p) \times p^2\mu^2(p^2)\mu(1) = -p\)

      那么 \(f(ip) = f(p^2) \times f(i) = (-p)f(i)\)。

    • \(p^k \mid i \ \ (k \geq 3)\) :

      此时,每一项中的 \(d\) 和 \(\frac nd\) 中必有一个有二次项,使得 \(\mu^2(d)\) 和 \(\mu(\frac nd)\) 中必有一个为 0,所以 \(f(p) = 0\)。

附上线性筛的代码:

\(Code\)

inline void euler(){
    f[1] = 1;
    for(int i = 2; i < N; ++i){
        if(!vis[i]) p[++tot] = i, f[i] = i - 1;
        for(int j = 1; j <= tot && i * p[j] < N; ++j){
            vis[i * p[j]] = 1;
            if(i % p[j]) f[i * p[j]] = f[i] * f[p[j]] % mod;
            else{
                if((i / p[j]) % p[j]) f[i * p[j]] = f[i / p[j]] * (mod - p[j]) % mod;
                break;
            }
        }
    }
}

至此,这道题就可以愉快的解决啦,计算答案的时候整除分块走一个即可。

我在预处理时把 \(T^k\) 和 \(f(T)\) 乘到了一起,具体为线性筛后面的第一个前缀和。

Code

#include <bits/stdc++.h>
#define uint unsigned int

using namespace std;

namespace IO{
    inline int read(){
        int x = 0;
        char ch = getchar();
        while(!isdigit(ch)) ch = getchar();
        while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
        return x;
    }

    template <typename T> inline void write(T x){
        if(x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
}
using namespace IO;

const int N = 2e7 + 10;
int T, Max, n, k, tot;
uint p[N], f[N], F[N];
bool vis[N];

inline uint qpow(uint a, uint b){
    uint res = 1;
    while(b){
        if(b & 1) res = res * a;
        a = a * a, b >>= 1;
    }
    return res;
}

inline void euler(int n){
    f[1] = F[1] = 1;
    for(int i = 2; i <= n; ++i){
        if(!vis[i]) p[++tot] = i, f[i] = i - 1, F[i] = qpow(i, k);
        for(int j = 1; j <= tot && i * p[j] <= n; ++j){
            vis[i * p[j]] = 1;
            F[i * p[j]] = F[i] * F[p[j]];
            if(i % p[j]) f[i * p[j]] = f[i] * f[p[j]];
            else{
                if((i / p[j]) % p[j]) f[i * p[j]] = -p[j] * f[i / p[j]];
                break;
            }
        }
    }
    for(int i = 1; i <= n; ++i) f[i] = (f[i - 1] + f[i] * F[i]), F[i] = (F[i] + F[i - 1]);
    for(int i = 1; i <= n; ++i) F[i] = (F[i] + F[i - 1]);
}

inline uint S(int n){
    return F[n << 1] - (F[n] << 1);
}

inline uint solve(int n){
    uint res = 0;
    for(int l = 1, r; l <= n; l = r + 1){
        r = n / (n / l);
        res += S(n / l) * (f[r] - f[l - 1]);
    }
    return res;
}

signed main(){
    T = read(), Max = read(), k = read();
    euler(Max << 1);
    while(T--) write(solve(read())), puts("");
    return 0;
}

\[\_EOF\_ \]

标签:lfloor,P6222,frac,加强版,题解,sum,rfloor,mu,2n
来源: https://www.cnblogs.com/xixike/p/15699767.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有