莫比乌斯反演例题集---(自用)

参考:大佬1 大佬2 大佬3 大佬4

P3455 [POI2007]ZAP-Queries

求 解 ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = k ] 求解\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k] i=1nj=1m[gcd(i,j)=k]
反 演 过 程 : 反演过程:
∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = k ] \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=k] i=1nj=1m[gcd(i,j)=k]

∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ m k ⌋ ε [ g c d ( i , j ) = 1 ] \sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{m}{k} \right \rfloor}\varepsilon[gcd(i,j)=1] i=1knj=1kmε[gcd(i,j)=1]

枚 举 d : 枚举d: d

∑ d = 1 ⌊ m i n ( ⌊ n k ⌋ , ⌊ m k ⌋ ) ⌋ μ ( d ) ⌊ n k d ⌋ ⌊ m k d ⌋ \sum_{d=1}^{\left \lfloor min(\left \lfloor \frac{n}{k} \right \rfloor,\left \lfloor \frac{m}{k} \right \rfloor)\right \rfloor}\mu(d)\left \lfloor \frac{n}{kd} \right \rfloor \left \lfloor \frac{m}{kd} \right \rfloor d=1min(kn,km)μ(d)kdnkdm

先 预 处 理 μ , 然 后 整 数 分 块 做 , 复 杂 度 为 O ( n + T n ) \red{先预处理\mu,然后整数分块做,复杂度为O(n + T\sqrt n)} μO(n+Tn )

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 5e5 + 10;

int mu[N]; // 莫比乌斯函数
bool is_prime[N];
int prime[N];
int cnt;

ll sum[N]; // 记录莫比乌斯函数前缀和


void Mobi() // 莫比乌斯函数初始化
{
    
    
    mu[1] = 1;
    is_prime[0] = is_prime[1] = true;
    for(int i = 2;i < N; i++) {
    
    
        if (!is_prime[i]) {
    
    
            mu[i] = -1;
            prime[++cnt] = i;
        }
        for (int j = 1; j <= cnt && i * prime[j] < N; j++) {
    
    
            is_prime[i * prime[j]] = true;
            if (i % prime[j] == 0) {
    
    
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
    }

    for(int i = 1;i < N; i++) {
    
    
        sum[i] = sum[i - 1] + mu[i];
    }
}

ll k;

ll Ans(ll n, ll m) {
    
    
    ll ans = 0;
    n /= k, m /= k;
    int mx = min(n, m);
    for(int l = 1, r;l <= mx; l = r + 1) {
    
    
        r = min(n / (n / l), m / (m / l));
        ans += (n / l) * (m / l) * (sum[r] - sum[l - 1]);
    }
    return ans;
}

void solve() {
    
    
    Mobi();
    int T;
    cin >> T;
    while(T--) {
    
    
        ll n, m;
        cin >> n >> m >> k;
        cout << Ans(n, m) << endl;
    }
}


signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

P2257 YY的GCD

求 解 ∑ p ∈ p r i m e ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] 求解\sum_{p\in prime}\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=p] pprimei=1nj=1m[gcd(i,j)=p]
反 演 过 程 和 上 面 几 乎 一 样 , 就 多 了 一 维 p 为 质 数 的 情 况 , 直 接 化 简 为 : 反演过程和上面几乎一样,就多了一维p为质数的情况,直接化简为: p

∑ p ∈ p r i m e ∑ d = 1 ⌊ m i n ( ⌊ n p ⌋ , ⌊ m p ⌋ ) ⌋ μ ( d ) ⌊ n p d ⌋ ⌊ m p d ⌋ \sum_{p\in prime}\sum_{d=1}^{\left \lfloor min(\left \lfloor \frac{n}{p} \right \rfloor,\left \lfloor \frac{m}{p} \right \rfloor)\right \rfloor}\mu(d)\left \lfloor \frac{n}{pd} \right \rfloor \left \lfloor \frac{m}{pd} \right \rfloor pprimed=1min(pn,pm)μ(d)pdnpdm

这 里 的 复 杂 度 为 O ( n + T n n ) , 但 明 显 不 够 , 所 以 需 要 继 续 化 简 , 这 里 的 优 化 可 以 用 T 替 换 p d , 则 d = T p , 替 换 后 的 式 子 为 : 这里的复杂度为O(n+T\sqrt n \sqrt n),但明显不够,所以需要继续化简,这里的优化可以用T替换pd,则d=\frac{T}{p},替换后的式子为: O(n+Tn n )Tpdd=pT

∑ T = 1 m i n ( n , m ) ) ⌊ n T ⌋ ⌊ m T ⌋ ∑ p ∣ T    p ∈ p r i m e μ ( T p ) \sum_{T=1}^{min(n,m)})\left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor\sum_{p|T\;p\in prime}\mu(\frac{T}{p}) T=1min(n,m))TnTmpTpprimeμ(pT)

令 F ( x ) = ∑ p ∣ x    p ∈ p r i m e μ ( x p ) 令\blue{F(x)=\sum_{p|x\;p\in prime}\mu(\frac{x}{p})} F(x)=pxpprimeμ(px)

得 : 得:

∑ p ∈ p r i m e ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = p ] = ∑ T = 1 m i n ( n , m ) ⌊ n T ⌋ ⌊ m T ⌋ F ( T ) \sum_{p\in prime}\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=p]=\sum_{T=1}^{min(n,m)}\left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor F(T) pprimei=1nj=1m[gcd(i,j)=p]=T=1min(n,m)TnTmF(T)

O ( n ) 处 理 μ , O ( n l o g n ) 处 理 F , O ( n ) 询 问 分 块 , 即 复 杂 度 为 O ( n l o g n + T n ) \red{O(n)处理\mu,O(nlogn)处理F,O(\sqrt n)询问分块,即复杂度为O(nlogn + T\sqrt n)} O(n)μO(nlogn)FO(n )O(nlogn+Tn )

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 1e7 + 10;

int mu[N]; // 莫比乌斯函数
bool is_prime[N];
int prime[N];
int cnt;

ll sum[N]; // 记录莫比乌斯函数前缀和
ll F[N];


void Mobi() // 莫比乌斯函数初始化
{
    
    
    mu[1] = 1;
    is_prime[0] = is_prime[1] = true;
    for(int i = 2;i < N; i++) {
    
    
        if (!is_prime[i]) {
    
    
            mu[i] = -1;
            prime[++cnt] = i;
        }
        for (int j = 1; j <= cnt && i * prime[j] < N; j++) {
    
    
            is_prime[i * prime[j]] = true;
            if (i % prime[j] == 0) {
    
    
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
    }

    for(int i = 1;i <= cnt; i++) {
    
    
        for(int j = 1;j * prime[i] < N; j++) {
    
    
            F[j * prime[i]] += mu[j];
        }
    }

    for(int i = 1;i < N; i++) {
    
    
        F[i] += F[i - 1];
    }
}

ll k;

ll Ans(ll N, ll M) {
    
    
    ll ans = 0;
    ll n = N, m = M;
    int mx = min(n, m);
    for (int l = 1, r; l <= mx; l = r + 1) {
    
    
        r = min(n / (n / l), m / (m / l));
        ans += (n / l) * (m / l) * (F[r] - F[l - 1]);
    }
    return ans;
}

void solve() {
    
    
    Mobi();
    int T;
    cin >> T;
    while(T--) {
    
    
        ll n, m;
        cin >> n >> m;
        cout << Ans(n, m) << endl;
    }
}


signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

P1390 公约数的和

求 解 ∑ i = 1 n ∑ j = i + 1 n g c d ( i , j ) 求解\sum_{i=1}^n\sum_{j=i+1}^ngcd(i,j) i=1nj=i+1ngcd(i,j)

先 来 看 看 基 本 形 式 : 先来看看基本形式:
∑ i = 1 n ∑ j = 1 n g c d ( i , j ) \sum_{i=1}^n\sum_{j=1}^ngcd(i,j) i=1nj=1ngcd(i,j)
则 a n s = C a l c ( n , n ) − n ( n + 1 ) 2 2 , 首 先 减 去 g c d ( i , i ) 的 个 数 n ( n + 1 ) 2 , 然 后 减 去 g c d ( i , j ) = g c d ( j , i ) 的 个 数 , 直 接 除 2 即 可 , 则 : 则\blue{ans=\frac{Calc(n,n)-\frac{n(n+1)}{2}}{2}},首先减去gcd(i,i)的个数\frac{n(n+1)}{2},然后减去gcd(i,j)=gcd(j,i)的个数,直接除2即可,则: ans=2Calc(n,n)2n(n+1)gcd(i,i)2n(n+1)gcd(i,j)=gcd(j,i)2
∑ i = 1 n ∑ j = 1 n ∑ k = 1 n k [ g c d ( i , j ) = k ] \sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^nk[gcd(i,j)=k] i=1nj=1nk=1nk[gcd(i,j)=k]

枚 举 k : 枚举k: k

∑ k = 1 n k ∑ i = 1 ⌊ n k ⌋ ∑ j = ⌊ i + 1 k ⌋ ⌊ n k ⌋ [ g c d ( i , j ) = 1 ] \sum_{k=1}^nk\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=\left \lfloor \frac{i+1}{k} \right \rfloor}^{\left \lfloor \frac{n}{k} \right \rfloor}[gcd(i,j)=1] k=1nki=1knj=ki+1kn[gcd(i,j)=1]

∑ k = 1 n k ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ n k ⌋ ∑ d ∣ i    d ∣ j μ ( d ) \sum_{k=1}^nk\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{d|i\;d|j}\mu(d) k=1nki=1knj=1kndidjμ(d)

∑ k = 1 n k ∑ d = 1 ⌊ n k ⌋ μ ( d ) ∑ i = 1 ⌊ n k d ⌋ ∑ j = 1 ⌊ n k d ⌋ 1 \sum_{k=1}^nk\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\mu(d)\sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}1 k=1nkd=1knμ(d)i=1kdnj=1kdn1

∑ k = 1 n k ∑ d = 1 ⌊ n k ⌋ μ ( d ) ( ⌊ n k d ⌋ ) 2 \sum_{k=1}^nk\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\mu(d)(\left \lfloor \frac{n}{kd} \right \rfloor)^2 k=1nkd=1knμ(d)(kdn)2

令 T = k d 并 枚 举 T , 得 : 令\blue{T=kd并枚举T},得: T=kdT

∑ T = 1 n ∑ d ∣ T μ ( d ) T d ( ⌊ n T ⌋ ) 2 \sum_{T=1}^n\sum_{d|T}\mu(d)\frac{T}{d}(\left \lfloor \frac{n}{T} \right \rfloor)^2 T=1ndTμ(d)dT(Tn)2

中 间 部 分 有 ∑ d ∣ T μ ( d ) T d = φ ( T ) , 因 为 φ = μ ∗ i d , 即 得 : 中间部分有\blue{\sum_{d|T}\mu(d)\frac{T}{d}=\varphi (T),因为\varphi =\mu * id},即得: dTμ(d)dT=φ(T)φ=μid

∑ T = 1 n φ ( T ) ( ⌊ n T ⌋ ) 2 \sum_{T=1}^n\varphi (T)(\left \lfloor \frac{n}{T} \right \rfloor)^2 T=1nφ(T)(Tn)2

则 最 终 答 案 为 : 则最终答案为:

a n s = ∑ T = 1 n φ ( T ) ( ⌊ n T ⌋ ) 2 − n ( n + 1 ) 2 2 \red{ans=\frac{\sum_{T=1}^n\varphi (T)(\left \lfloor \frac{n}{T} \right \rfloor)^2-\frac{n(n+1)}{2}}{2}} ans=2T=1nφ(T)(Tn)22n(n+1)

O ( n ) 预 处 理 φ , n 询 问 分 块 , 总 时 间 复 杂 度 为 O ( n + n ) \red{O(n)预处理\varphi,\sqrt n询问分块,总时间复杂度为O(n+\sqrt n)} O(n)φn O(n+n )

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const ll P = 1e9 + 7;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 2e6 + 10;

int phi[N];
bool is_prime[N];
int prime[N];
int tot;

ll f[N];

void Euler()
{
    
    
    phi[1] = 1;
    is_prime[1] = true;
    for(int i = 2;i < N; i++){
    
    
        if(!is_prime[i]) {
    
    
            phi[i] = i - 1;
            prime[++tot] = i;
        }
        for(int j = 1;j <= tot && i * prime[j] < N; j++){
    
    
            is_prime[i * prime[j]] = true;
            if(i % prime[j]) {
    
    
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
            else{
    
    
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
        }
    }

    for(int i = 1;i < N; i++) {
    
    
        f[i] = f[i - 1] + phi[i];
    }
}

ll Calc(ll n) {
    
    
    ll ans = 0;

    for(ll l = 1, r;l <= n;l = r + 1) {
    
    
        r = min(n, n / (n / l));
        ans += (f[r] - f[l - 1]) * (n / l) * (n / l);
    }
    return ans;
}

void solve() {
    
    
    Euler();
    ll n;
    cin >> n;
    cout << (Calc(n) - n * (n + 1) / 2) / 2 << endl;
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

P1829 [国家集训队]Crash的数字表格 / JZPTAB

求 解 ∑ i = 1 n ∑ j = 1 m l c m ( i , j ) 求解\sum_{i=1}^n\sum_{j=1}^mlcm (i,j) i=1nj=1mlcm(i,j)

由 g c d 和 l c m 之 间 的 关 系 得 : 由gcd和lcm之间的关系得: gcdlcm

∑ i = 1 n ∑ j = 1 m i j g c d ( i , j ) \sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)} i=1nj=1mgcd(i,j)ij

∑ k = 1 m i n ( n , m ) ∑ i = 1 n ∑ j = 1 m i j k [ g c d ( i , j ) = k ] \sum_{k=1}^{min(n,m)}\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{k}[gcd(i,j)=k] k=1min(n,m)i=1nj=1mkij[gcd(i,j)=k]

∑ k = 1 m i n ( n , m ) ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ m k ⌋ i j k 2 k [ g c d ( i , j ) = 1 ] \sum_{k=1}^{min(n,m)}\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{m}{k} \right \rfloor}\frac{ijk^2}{k}[gcd(i,j)=1] k=1min(n,m)i=1knj=1kmkijk2[gcd(i,j)=1]

∑ k = 1 m i n ( n , m ) k ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ m k ⌋ i j ∑ d ∣ i    d ∣ j μ ( d ) \sum_{k=1}^{min(n,m)}k\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{m}{k} \right \rfloor}ij\sum_{d|i\;d|j}\mu(d) k=1min(n,m)ki=1knj=1kmijdidjμ(d)

枚 举 d 得 : 枚举d得: d

∑ k = 1 m i n ( n , m ) k ∑ d = 1 m i n ( ⌊ n k ⌋ , ⌊ m k ⌋ ) μ ( d ) ∑ i = 1 ⌊ n k d ⌋ i d ∑ j = 1 ⌊ m k d ⌋ j d \sum_{k=1}^{min(n,m)}k\sum_{d=1}^{min(\left \lfloor \frac{n}{k} \right \rfloor,\left \lfloor \frac{m}{k} \right \rfloor)}\mu(d)\sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}id\sum_{j=1}^{\left \lfloor \frac{m}{kd} \right \rfloor}jd k=1min(n,m)kd=1min(kn,km)μ(d)i=1kdnidj=1kdmjd

∑ k = 1 m i n ( n , m ) k ∑ d = 1 m i n ( ⌊ n k ⌋ , ⌊ m k ⌋ ) μ ( d ) d 2 ∑ i = 1 ⌊ n k d ⌋ i ∑ j = 1 ⌊ m k d ⌋ j \sum_{k=1}^{min(n,m)}k\sum_{d=1}^{min(\left \lfloor \frac{n}{k} \right \rfloor,\left \lfloor \frac{m}{k} \right \rfloor)}\mu(d)d^2\sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}i\sum_{j=1}^{\left \lfloor \frac{m}{kd} \right \rfloor}j k=1min(n,m)kd=1min(kn,km)μ(d)d2i=1kdnij=1kdmj

令 f ( x ) = ∑ i = 1 x i , F ( n , m ) = ∑ d = 1 m i n ( n , m ) μ ( d ) d 2 f ( n d ) f ( m d ) , 得 : 令\blue{f(x)=\sum_{i=1}^{x}i,F(n,m)=\sum_{d=1}^{min(n,m)}\mu(d)d^2f(\frac{n}{d})f(\frac{m}{d})},得: f(x)=i=1xiF(n,m)=d=1min(n,m)μ(d)d2f(dn)f(dm)

∑ k = 1 m i n ( n , m ) k F ( ⌊ n k ⌋ , ⌊ m k ⌋ ) \sum_{k=1}^{min(n,m)}kF(\left \lfloor\frac{n}{k}\right \rfloor,\left \lfloor\frac{m}{k}\right \rfloor) k=1min(n,m)kF(kn,km)

O ( n ) 处 理 μ , O ( 1 ) 处 理 f ( 等 差 数 列 , 在 计 算 F 的 过 程 中 直 接 直 接 计 算 ) , O ( n ) 分 块 询 问 F , 答 案 分 块 询 问 O ( n ) , 总 复 杂 度 为 O ( n + n 3 4 ) \red{O(n)处理\mu,O(1)处理f(等差数列,在计算F的过程中直接直接计算),O(\sqrt {\sqrt n})分块询问F,答案分块询问O(\sqrt n),总复杂度为O(n+n^{\frac{3}{4}})} O(n)μ,O(1)fFO(n )FO(n )O(n+n43)

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 1e7 + 10;

const ll mod = 20101009;

int mu[N]; // 莫比乌斯函数
bool is_prime[N];
int prime[N];
int cnt;

ll sum[N];

void Mobi() // 莫比乌斯函数初始化
{
    
    
    mu[1] = 1;
    is_prime[0] = is_prime[1] = true;
    for(int i = 2;i < N; i++) {
    
    
        if (!is_prime[i]) {
    
    
            mu[i] = -1;
            prime[++cnt] = i;
        }
        for (int j = 1; j <= cnt && i * prime[j] < N; j++) {
    
    
            is_prime[i * prime[j]] = true;
            if (i % prime[j] == 0) {
    
    
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
    }

    for(int i = 1;i < N; i++) {
    
    
        sum[i] = (sum[i - 1] + mu[i] * i % mod * i % mod) % mod;
    }
}

ll Ans(ll n, ll m)
{
    
    
    ll inv2 = (mod + 1) / 2;
    ll ans = 0;
    ll p = min(n, m);
    for(int k = 1;k <= p; k++) {
    
    
        int x = n / k, y = m / k, P = min(x, y);
        ll Sum = 0;
        for(int l = 1, r;l <= P; l = r + 1) {
    
    
            r = min(x / (x / l), (y / (y / l)));
            Sum = (Sum + (sum[r] - sum[l - 1] + mod) % mod * (1 + x / l) % mod * (x / l) % mod * inv2 % mod * (1 + y / l) % mod * (y / l) % mod * inv2 % mod) % mod;
        }
        ans = (ans + Sum * k % mod) % mod;
    }
    return ans;
}

void solve() {
    
    
    Mobi();
    ll n, m;
    cin >> n >> m;
    cout << Ans(n, m) << endl;

}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

P3768 简单的数学题

求 解 ∑ i = 1 n ∑ j = 1 n i j ( g c d ( i , j ) )    m o d    p 求解\sum_{i=1}^n\sum_{j=1}^nij(gcd(i,j))\;mod \;p i=1nj=1nij(gcd(i,j))modp
∑ k = 1 n ∑ i = 1 n ∑ j = 1 n i j k [ g c d ( i , j ) = k ] \sum_{k=1}^n\sum_{i=1}^n\sum_{j=1}^nijk[gcd(i,j)=k] k=1ni=1nj=1nijk[gcd(i,j)=k]

∑ k = 1 n k ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ n k ⌋ i j k 2 [ g c d ( i , j ) = 1 ] \sum_{k=1}^nk\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{n}{k} \right \rfloor}ijk^2[gcd(i,j)=1] k=1nki=1knj=1knijk2[gcd(i,j)=1]

∑ k = 1 n k 3 ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ n k ⌋ i j ∑ d ∣ i    d ∣ j μ ( d ) \sum_{k=1}^nk^3\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{n}{k} \right \rfloor}ij\sum_{d|i\;d|j}\mu(d) k=1nk3i=1knj=1knijdidjμ(d)

∑ k = 1 n k 3 ∑ d = 1 ⌊ n k ⌋ μ ( d ) ∑ i = 1 ⌊ n k d ⌋ i d ∑ j = 1 ⌊ n k d ⌋ j d \sum_{k=1}^nk^3\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\mu(d)\sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}id\sum_{j=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}jd k=1nk3d=1knμ(d)i=1kdnidj=1kdnjd

∑ k = 1 n k 3 ∑ d = 1 ⌊ n k ⌋ μ ( d ) d 2 ∑ i = 1 ⌊ n k d ⌋ i ∑ j = 1 ⌊ n k d ⌋ j \sum_{k=1}^nk^3\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\mu(d)d^2\sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}i\sum_{j=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}j k=1nk3d=1knμ(d)d2i=1kdnij=1kdnj

令 f ( x ) = ∑ i = 1 x i , 则 式 子 变 为 : 令\blue{f(x)=\sum_{i=1}^xi},则式子变为: f(x)=i=1xi

∑ k = 1 n k 3 ∑ d = 1 ⌊ n k ⌋ μ ( d ) d 2 f 2 ( n k d ) \sum_{k=1}^nk^3\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\mu(d)d^2f^2(\frac{n}{kd}) k=1nk3d=1knμ(d)d2f2(kdn)

到 这 里 , 时 间 复 杂 度 为 O ( n + n n ) , 我 没 尝 试 过 , 但 是 还 可 以 继 续 化 简 , 化 简 方 法 有 替 换 , 用 T 替 换 k d , 则 : 到这里,时间复杂度为O(n+n\sqrt n),我没尝试过,但是还可以继续化简,化简方法有替换,用T替换kd,则: O(n+nn )Tkd

∑ T = 1 n f 2 ( n T ) T 2 ∑ k ∣ T k ∗ μ ( T k ) \sum_{T=1}^nf^2(\frac{n}{T})T^2\sum_{k|T}k*\mu(\frac{T}{k}) T=1nf2(Tn)T2kTkμ(kT)

∑ T = 1 n f 2 ( n T ) T 2 ( i d ∗ μ ) T \sum_{T=1}^nf^2(\frac{n}{T})T^2\red{(id*\mu)T} T=1nf2(Tn)T2(idμ)T

∑ T = 1 n f 2 ( n T ) T 2 φ ( T ) \sum_{T=1}^nf^2(\frac{n}{T})T^2\red{\varphi (T)} T=1nf2(Tn)T2φ(T)

可 以 杜 教 筛 筛 T 2 φ ( T ) 的 前 缀 和 , 因 为 n 最 高 有 1 0 10 , 明 显 数 组 存 不 下 , 所 以 对 于 5 e 6 可 以 用 数 组 直 接 过 度 求 前 缀 和 , 对 于 后 面 就 可 以 用 杜 教 筛 求 前 缀 和 , 然 后 用 m a p 存 下 ( S T L 的 好 处 ) , 过 程 如 下 : \blue{可以杜教筛筛T^2\varphi (T)的前缀和,因为n最高有10^{10},明显数组存不下,所以对于5e6可以用数组直接过度求前缀和,对于后面就可以用杜教筛求前缀和,然后用map存下(STL的好处),过程如下:} T2φ(T)n10105e6mapSTL

参 考 : 参考: 杜教筛

先 看 杜 教 筛 的 基 本 形 式 ( 与 上 面 无 关 ) : 设 S ( n ) = ∑ i = 1 n f ( i ) , 定 义 一 个 新 函 数 为 g , 则 有 先看杜教筛的基本形式(与上面无关):设S(n)=\sum_{i=1}^{n}f(i),定义一个新函数为g,则有 ()S(n)=i=1nf(i)g

∑ i = 1 n ( f ∗ g ) i \sum_{i=1}^n(f*g)i i=1n(fg)i

∑ i = 1 n ∑ x y = i f ( x ) g ( y ) \sum_{i=1}^n\sum_{xy=i}f(x)g(y) i=1nxy=if(x)g(y)

∑ y = 1 n g ( y ) ∑ x y ≤ n f ( x ) \sum_{y=1}^ng(y)\sum_{xy\leq n}f(x) y=1ng(y)xynf(x)

∑ y = 1 n g ( y ) ∑ x = 1 ⌊ n y ⌋ f ( x ) \sum_{y=1}^ng(y)\sum_{x=1}^{\left \lfloor \frac{n}{y} \right \rfloor}f(x) y=1ng(y)x=1ynf(x)

∑ y = 1 n g ( y ) S ( ⌊ n y ⌋ ) \sum_{y=1}^ng(y)S(\left \lfloor \frac{n}{y} \right \rfloor) y=1ng(y)S(yn)

则 有 : 则有:

∑ i = 1 n ( f ∗ g ) i = g ( 1 ) S ( n ) + ∑ y = 2 n g ( y ) S ( ⌊ n y ⌋ ) \sum_{i=1}^n(f*g)i=g(1)S(n)+\sum_{y=2}^ng(y)S(\left \lfloor \frac{n}{y} \right \rfloor) i=1n(fg)i=g(1)S(n)+y=2ng(y)S(yn)

S ( n ) = ∑ i = 1 n ( f ∗ g ) i − ∑ y = 2 n g ( y ) S ( ⌊ n y ⌋ ) g ( 1 ) \red{S(n)=\frac{\sum_{i=1}^n(f*g)i-\sum_{y=2}^ng(y)S(\left \lfloor \frac{n}{y} \right \rfloor)}{g(1)}} S(n)=g(1)i=1n(fg)iy=2ng(y)S(yn)

对 于 本 题 , 要 找 到 合 适 的 g 函 数 , 因 为 我 们 求 的 前 缀 和 为 S ( n ) = ∑ i = 1 n i 2 φ ( i ) , f ( i ) = i 2 φ ( i ) , 所 以 设 g ( n ) = n 2 。 对于本题,要找到合适的g函数,因为我们求的前缀和为S(n)=\sum_{i=1}^ni^2\varphi(i),f(i)=i^2\varphi(i),所以设g(n)=n^2。 gS(n)=i=1ni2φ(i),f(i)=i2φ(i)g(n)=n2

∑ i = 1 n g ( i ) = x ( x + 1 ) ( 2 x + 1 ) 6 \sum_{i=1}^ng(i)=\frac{x(x+1)(2x+1)}{6} i=1ng(i)=6x(x+1)(2x+1)

( f ∗ g ) x = ∑ d ∣ x f ( d ) g ( x d ) = ∑ d ∣ x d 2 φ ( d ) x 2 d 2 = x 2 ∑ d ∣ x φ ( d ) = x 2 i d ( x ) = x 3 (f*g)x=\sum_{d|x}f(d)g(\frac{x}{d})=\sum_{d|x}d^2\varphi(d)\frac{x^2}{d^2}=x^2\sum_{d|x}\varphi(d)=x^2id(x)=x^3 (fg)x=dxf(d)g(dx)=dxd2φ(d)d2x2=x2dxφ(d)=x2id(x)=x3

∑ i = 1 n ( f ∗ g ) i = ∑ i = 1 n i 3 = x 2 ( x + 1 ) 2 4 \sum_{i=1}^n(f*g)i=\sum_{i=1}^ni^3=\frac{x^2(x+1)^2}{4} i=1n(fg)i=i=1ni3=4x2(x+1)2

S ( n ) = n 2 ( n + 1 ) 2 4 − ∑ y = 2 n g ( y ) S ( ⌊ n y ⌋ ) \red{S(n)=\frac{n^2(n+1)^2}{4}-\sum_{y=2}^ng(y)S(\left \lfloor \frac{n}{y} \right \rfloor)} S(n)=4n2(n+1)2y=2ng(y)S(yn)

O ( n 2 3 ) 处 理 T 2 φ ( T ) 的 前 缀 和 , f 可 以 O ( 1 ) 算 出 , O ( n ) 询 问 分 块 , 总 时 间 复 杂 度 为 O ( n 2 3 ) \red{O(n^{\frac{2}{3}})处理T^2\varphi (T)的前缀和,f可以O(1)算出,O(\sqrt n) 询问分块,总时间复杂度为O(n^\frac{2}{3})} O(n32)T2φ(T)fO(1)O(n )O(n32)

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 5e6 + 10;

ll n, mod, inv4, inv6;
ll phi[N];
bool is_prime[N];
int prime[N];
int tot;

ll sum[N];

void Get_phi() {
    
    
    phi[1] = 1;
    is_prime[1] = true;
    for(int i = 2;i <= N; i++){
    
    
        if(!is_prime[i]) {
    
    
            phi[i] = i - 1;
            prime[++tot] = i;
        }
        for(int j = 1;j <= tot && i * prime[j] < N; j++){
    
    
            is_prime[i * prime[j]] = true;
            if(i % prime[j]) {
    
    
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
            else{
    
    
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
        }
    }
    for(int i = 1;i < N; i++) {
    
    
        sum[i] = (sum[i - 1] + (ll)phi[i] * i % mod * i % mod) % mod;
    }
}

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

ll sum1(ll x) {
    
    x %= mod; return (1 + x) % mod * x % mod * (1 + x) % mod * x % mod * inv4 % mod;}
ll sum2(ll x) {
    
    x %= mod; return x % mod * (1 + x) % mod * (2 * x + 1) % mod * inv6 % mod;}

map<ll, ll> mp;

ll Calc(ll x) {
    
    
    if(x < N) return sum[x];
    if(mp[x]) return mp[x];
    ll num = sum1(x);
    for(ll l = 2, r;l <= x;l = r + 1) {
    
    
        r = x / (x / l);
        num = (num - Calc(x / l) % mod * (sum2(r) - sum2(l - 1) + mod) % mod + mod) % mod;
    }
    return mp[x] = num;
}

ll Ans() {
    
    
    ll ans = 0;
    for(ll l = 1, r;l <= n; l = r + 1) {
    
    
        r = n / (n / l);
        ans = (ans + sum1(n / l) % mod * (Calc(r) - Calc(l - 1) % mod + mod) % mod) % mod;
    }
    return ans;
}

void solve() {
    
    
    cin >> mod >> n;
    Get_phi();
    inv4 = quick_pow(4, mod - 2);
    inv6 = quick_pow(6, mod - 2);
    cout << Ans() << endl;
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

P3327 [SDOI2015]约数个数和

求 解 ∑ i = 1 n ∑ j = 1 m d ( i j ) 求解\sum_{i=1}^n\sum_{j=1}^md (ij) i=1nj=1md(ij)

约 数 的 重 要 性 质 : ( i j ) = ∑ x ∣ i ∑ y ∣ j [ g c d ( x , y ) = 1 ] \red{约数的重要性质:(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y )=1]} :(ij)=xiyj[gcd(x,y)=1]

https://www.cnblogs.com/sun123zxy/p/12295533.html

得 : 得:
∑ i = 1 n ∑ j = 1 m ∑ x ∣ i ∑ y ∣ j [ g c d ( x , y ) = 1 ] \sum_{i=1}^n\sum_{j=1}^m\sum_{x|i}\sum_{y|j}[gcd(x,y )=1] i=1nj=1mxiyj[gcd(x,y)=1]

改 变 枚 举 顺 序 , 枚 举 x 和 y : 改变枚举顺序,枚举x和y: xy:

∑ x = 1 n ∑ y = 1 m ⌊ n x ⌋ ⌊ n y ⌋ [ g c d ( x , y ) = 1 ] \sum_{x=1}^n\sum_{y=1}^m\left \lfloor \frac{n}{x} \right \rfloor\left \lfloor \frac{n}{y} \right \rfloor[gcd(x,y)=1] x=1ny=1mxnyn[gcd(x,y)=1]

∑ i = 1 n ∑ j = 1 m ⌊ n i ⌋ ⌊ n j ⌋ [ g c d ( i , j ) = 1 ] \sum_{i=1}^n\sum_{j=1}^m\left \lfloor \frac{n}{i} \right \rfloor\left \lfloor \frac{n}{j} \right \rfloor[gcd(i,j)=1] i=1nj=1minjn[gcd(i,j)=1]

后 面 套 用 前 面 得 : 后面套用前面得:

∑ i = 1 n ∑ j = 1 m ⌊ n i ⌋ ⌊ n j ⌋ ∑ d ∣ i    d ∣ j μ ( d ) \sum_{i=1}^n\sum_{j=1}^m\left \lfloor \frac{n}{i} \right \rfloor\left \lfloor \frac{n}{j} \right \rfloor\sum_{d|i\;d|j}\mu(d) i=1nj=1minjndidjμ(d)

枚 举 d 得 : 枚举d得: d

∑ d = 1 m i n ( n , m ) μ ( d ) ∑ i = 1 n ∑ j = 1 m ⌊ n i ⌋ ⌊ n j ⌋ [ d ∣ g c d ( i , j ) ] \sum_{d=1}^{min(n,m)}\mu(d)\sum_{i=1}^n\sum_{j=1}^m\left \lfloor \frac{n}{i} \right \rfloor\left \lfloor \frac{n}{j} \right \rfloor[d|gcd(i,j)] d=1min(n,m)μ(d)i=1nj=1minjn[dgcd(i,j)]

由 于 [ d ∣ g c d ( i , j ) ] 成 立 的 条 件 为 d 是 g c d ( i , j ) 的 约 数 , 所 以 可 以 把 枚 举 i , j 变 换 为 枚 举 d i , d j , 从 而 [ 1 ∣ g c d ( i , j ) ] 可 以 省 略 。 得 : 由于[d|gcd(i,j)]成立的条件为d是gcd(i,j)的约数,所以可以把枚举i,j变换为枚举di,dj,从而[1|gcd(i,j)]可以省略。得: [dgcd(i,j)]dgcd(i,j)i,jdi,dj[1gcd(i,j)]

∑ d = 1 m i n ( n , m ) μ ( d ) ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ ⌊ n i d ⌋ ⌊ n j d ⌋ \sum_{d=1}^{min(n,m)}\mu(d)\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\sum_{j=1}^{\left \lfloor\frac{m}{d}\right \rfloor}\left \lfloor \frac{n}{id} \right \rfloor\left \lfloor \frac{n}{jd} \right \rfloor d=1min(n,m)μ(d)i=1dnj=1dmidnjdn

∑ d = 1 m i n ( n , m ) μ ( d ) ∑ i = 1 ⌊ n d ⌋ ⌊ n i d ⌋ ∑ j = 1 ⌊ m d ⌋ ⌊ n j d ⌋ \sum_{d=1}^{min(n,m)}\mu(d)\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\left \lfloor \frac{n}{id} \right \rfloor\sum_{j=1}^{\left \lfloor\frac{m}{d}\right \rfloor}\left \lfloor \frac{n}{jd} \right \rfloor d=1min(n,m)μ(d)i=1dnidnj=1dmjdn

令 f ( x ) = ∑ i = 1 x ⌊ x i ⌋ , 则 : 令\blue{f(x)=\sum_{i=1}^x\left \lfloor \frac{x}{i} \right \rfloor},则: f(x)=i=1xix

∑ d = 1 m i n ( n , m ) μ ( d ) f ( n d ) f ( m d ) \sum_{d=1}^{min(n,m)}\mu(d)f(\frac{n}{d})f(\frac{m}{d}) d=1min(n,m)μ(d)f(dn)f(dm)

O ( n ) 处 理 μ 和 其 前 缀 和 , O ( n n ) 处 理 f , O ( n ) 询 问 分 块 , 总 复 杂 度 为 O ( n n + T n ) \red{O(n)处理\mu和其前缀和,O(n\sqrt n)处理f,O(\sqrt n)询问分块,总复杂度为O(n\sqrt n+T\sqrt n)} O(n)μO(nn )fO(n )O(nn +Tn )

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 5e4 + 10;

ll mu[N]; // 莫比乌斯函数
bool is_prime[N];
int prime[N];
int cnt;

ll f[N];

void Mobi() // 莫比乌斯函数初始化
{
    
    
    mu[1] = 1;
    is_prime[0] = is_prime[1] = true;
    for(int i = 2;i < N; i++) {
    
    
        if (!is_prime[i]) {
    
    
            mu[i] = -1;
            prime[++cnt] = i;
        }
        for (int j = 1; j <= cnt && i * prime[j] < N; j++) {
    
    
            is_prime[i * prime[j]] = true;
            if (i % prime[j] == 0) {
    
    
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
    }

    for(int i = 1;i < N; i++) {
    
    
        mu[i] += mu[i - 1];
    }

    for(int i = 1;i < N; i++) {
    
    
        ll ans = 0;
        for(int l = 1, r;l <= i; l = r + 1) {
    
    
            r = i / (i / l);
            ans += (r - l + 1) * (i / l);
        }
        f[i] = ans;
    }
}

ll Ans(ll n, ll m)
{
    
    
    ll ans = 0;
    ll k = min(n, m);

    for(ll l = 1, r;l <= k; l = r + 1) {
    
    
        r = min(n / (n / l), m / (m / l));
        ans += (mu[r] - mu[l - 1]) * f[m / l] * f[n / l];
    }
    return ans;
}


void solve() {
    
    
    int T;
    Mobi();
    cin >> T;
    while(T--) {
    
    
        ll n, m;
        cin >> n >> m;
        cout << Ans(n, m) << endl;
    }
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

P3312 [SDOI2014]数表

求 解 ∑ i = 1 n ∑ j = 1 m ∑ d ∣ i    d ∣ j d [ ∑ d ∣ i    d ∣ j d ≤ a ] 求解\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i\;d|j}d[\sum_{d|i\;d|j}d\leq a] i=1nj=1mdidjd[didjda]

令 F ( x ) = ∑ i ∣ x i , 则 得 : 令\blue {F(x)=\sum_{i|x}i},则得: F(x)=ixi

∑ i = 1 n ∑ j = 1 m F ( g c d ( i , j ) ) [ F ( g c d ( i , j ) ) ≤ a ] \sum_{i=1}^n\sum_{j=1}^m F(gcd(i,j))[F(gcd(i,j))\leq a] i=1nj=1mF(gcd(i,j))[F(gcd(i,j))a]

∑ d = 1 m i n ( n , m ) ∑ i = 1 n ∑ j = 1 m F ( d ) [ g c d ( i , j ) = d ] [ F ( d ) ≤ a ] \sum_{d=1}^{min(n,m)}\sum_{i=1}^n\sum_{j=1}^m F(d)[gcd(i,j)=d][F(d)\leq a] d=1min(n,m)i=1nj=1mF(d)[gcd(i,j)=d][F(d)a]

∑ d = 1 m i n ( n , m ) F ( d ) [ F ( d ) ≤ a ] ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = d ] \sum_{d=1}^{min(n,m)}F(d)[F(d)\leq a]\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=d] d=1min(n,m)F(d)[F(d)a]i=1nj=1m[gcd(i,j)=d]

后 半 部 分 就 套 用 前 面 得 : 后半部分就套用前面得:

∑ d = 1 m i n ( n , m ) F ( d ) [ F ( d ) ≤ a ] ∑ d ′ = 1 m i n ( ⌊ n d ⌋ , ⌊ m d ⌋ ) μ ( d ′ ) ⌊ n d d ′ ⌋ ⌊ m d d ′ ⌋ \sum_{d=1}^{min(n,m)}F(d)[F(d)\leq a]\sum_{d^{'}=1}^{min(\left \lfloor \frac{n}{d} \right \rfloor, \left \lfloor \frac{m}{d} \right \rfloor)}\mu(d^{'})\left \lfloor \frac{n}{dd^{'}} \right \rfloor \left \lfloor \frac{m}{dd^{'}} \right \rfloor d=1min(n,m)F(d)[F(d)a]d=1min(dn,dm)μ(d)ddnddm

令 T 替 换 d d ′ 得 : 令T替换dd^{'}得: Tdd

∑ T = 1 m i n ( n , m ) ∑ d ∣ T F ( d ) μ ( T d ) ⌊ n T ⌋ ⌊ m T ⌋ [ F ( d ) ≤ a ] \sum_{T=1}^{min(n,m)}\sum_{d|T}F(d)\mu(\frac{T}{d})\left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor[F(d)\leq a] T=1min(n,m)dTF(d)μ(dT)TnTm[F(d)a]

∑ T = 1 m i n ( n , m ) ⌊ n T ⌋ ⌊ m T ⌋ ∑ d ∣ T F ( d ) μ ( T d ) [ F ( d ) ≤ a ] \sum_{T=1}^{min(n,m)}\left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor\sum_{d|T}F(d)\mu(\frac{T}{d})[F(d)\leq a] T=1min(n,m)TnTmdTF(d)μ(dT)[F(d)a]

令 f ( x ) = ∑ d ∣ x F ( d ) μ ( x d ) [ F ( d ) ≤ a ] 得 : 令\blue{f(x)=\sum_{d|x}F(d)\mu(\frac{x}{d})[F(d)\leq a]}得: f(x)=dxF(d)μ(dx)[F(d)a]

∑ T = 1 m i n ( n , m ) ⌊ n T ⌋ ⌊ m T ⌋ f ( T ) \sum_{T=1}^{min(n,m)}\left \lfloor \frac{n}{T} \right \rfloor \left \lfloor \frac{m}{T} \right \rfloor f(T) T=1min(n,m)TnTmf(T)

O ( n ) 处 理 μ , O ( n l o g n ) 处 理 F , 对 于 每 次 询 问 的 a 值 可 以 离 线 排 序 , 树 状 数 组 维 护 f , 处 理 时 间 为 O ( n l o g 2 n ) , O ( n    l o g n ) 询 问 分 块 , 总 时 间 复 杂 度 为 O ( n l o g 2 n ) + T n    l o g n \red{O(n)处理\mu,O(nlogn)处理F,对于每次询问的a值可以离线排序,树状数组维护f,处理时间为O(nlog^{2}n),O(\sqrt n\; logn)询问分块,总时间复杂度为O(nlog^2n)+T\sqrt n\; logn} O(n)μO(nlogn)Fa线fO(nlog2n)O(n logn)O(nlog2n)+Tn logn

Code

由于作者离线的数据结构太菜,本题先咕咕咕

P3172 [CQOI2015]选数

求 解 ∑ i = L H ∑ j = L H . . . ∑ x = L H [ g c d ( i , j . . . x ) = k ] 求解\sum_{i=L}^H\sum_{j=L}^H...\sum_{x=L}^H[gcd(i,j...x)=k] i=LHj=LH...x=LH[gcd(i,j...x)=k]

本 题 求 n 个 数 的 g c d 为 k 的 个 数 , 根 据 上 面 套 路 , 将 H / k , L / k , 这 样 就 只 用 求 n 个 数 的 g c d 为 1 的 个 数 了 , 注 意 : 如 果 L 整 除 k , 则 L = L / k , 否 则 L = L / k + 1 , 就 是 向 上 取 整 , 那 么 有 一 种 办 法 非 常 好 , 就 让 L / k + ( k − 1 k ) , 即 : 本题求n个数的gcd为k的个数,根据上面套路,将H/k,L/k,这样就只用求n个数的gcd为1的个数了,注意:如果L整除k,则L=L/k,否则L=L/k+1,就是向上取整,那么有一种办法非常好,就让\blue{L/k+(\frac{k-1}{k})},即: ngcdkH/k,L/kngcd1LkL=L/kL=L/k+1L/k+(kk1)

∑ i = ⌊ L − 1 k ⌋ + 1 ⌊ H k ⌋ ∑ j = ⌊ L − 1 k ⌋ + 1 ⌊ H k ⌋ . . . ∑ x = ⌊ L − 1 k ⌋ + 1 ⌊ H k ⌋ [ g c d ( i , j . . . x ) = 1 ] \sum_{i={\left \lfloor \frac{L-1}{k} \right \rfloor+1}}^{\left \lfloor \frac{H}{k}\right \rfloor}\sum_{j={\left \lfloor \frac{L-1}{k} \right \rfloor+1}}^{\left \lfloor \frac{H}{k}\right \rfloor}...\sum_{x={\left \lfloor \frac{L-1}{k} \right \rfloor+1}}^{\left \lfloor \frac{H}{k}\right \rfloor}[gcd(i,j...x)=1] i=kL1+1kHj=kL1+1kH...x=kL1+1kH[gcd(i,j...x)=1]

∑ i = ⌊ L − 1 k ⌋ + 1 ⌊ H k ⌋ ∑ j = ⌊ L − 1 k ⌋ + 1 ⌊ H k ⌋ . . . ∑ x = ⌊ L − 1 k ⌋ + 1 ⌊ H k ⌋ ∑ d ∣ i    d ∣ j    . .    d ∣ x μ ( d ) \sum_{i={\left \lfloor \frac{L-1}{k} \right \rfloor+1}}^{\left \lfloor \frac{H}{k}\right \rfloor}\sum_{j={\left \lfloor \frac{L-1}{k} \right \rfloor+1}}^{\left \lfloor \frac{H}{k}\right \rfloor}...\sum_{x={\left \lfloor \frac{L-1}{k} \right \rfloor+1}}^{\left \lfloor \frac{H}{k}\right \rfloor}\sum_{d|i\;d|j\;..\;d|x}\mu(d) i=kL1+1kHj=kL1+1kH...x=kL1+1kHdidj..dxμ(d)

枚 举 d , 令 l = ⌊ L − 1 k ⌋ + 1 , r = ⌊ H k ⌋ : 枚举d,令\blue{l=\left \lfloor \frac{L-1}{k} \right \rfloor+1,r=\left \lfloor \frac{H}{k}\right \rfloor}: dl=kL1+1,r=kH

∑ d = 1 r μ ( d ) ∑ i = l r [ d ∣ i ] ∑ j = l r [ d ∣ j ] . . . ∑ x = l r [ d ∣ x ] \sum_{d=1}^r\mu(d)\sum_{i=l}^r[d|i]\sum_{j=l}^r[d|j]...\sum_{x=l}^r[d|x] d=1rμ(d)i=lr[di]j=lr[dj]...x=lr[dx]

只 有 当 i , j . . . x 都 是 d 的 倍 数 的 时 候 , 最 终 答 案 + 1 , 根 据 容 斥 原 理 , 那 么 在 [ l , r ] 中 d 倍 数 有 r d − l − 1 d , 对 于 所 有 的 i , j . . . x , 他 们 当 中 所 有 [ l , r ] 的 d 的 倍 数 的 个 数 有 ( r d − l − 1 d ) n , 即 为 : 只有当i,j...x都是d的倍数的时候,最终答案+1,根据容斥原理,那么在[l,r]中d倍数有\blue{\frac{r}{d}-\frac{l-1}{d}},对于所有的i,j...x,他们当中所有[l,r]的d的倍数的个数有\blue{(\frac{r}{d}-\frac{l-1}{d})^n},即为: ij...xd+1[l,r]ddrdl1ij...x[l,r]d(drdl1)n

∑ d = 1 r μ ( d ) ∗ ( r d − l − 1 d ) n \sum_{d=1}^{r}\mu(d)*(\frac{r}{d}-\frac{l-1}{d})^n d=1rμ(d)(drdl1)n

这 里 的 H 非 常 大 , 如 果 用 线 性 筛 去 处 理 μ , 会 直 接 W a 掉 , 因 为 没 法 处 理 到 1 0 9 次 方 那 么 大 的 前 缀 和 , 数 组 也 开 不 了 那 么 大 。 后 果 : 这里的H非常大,如果用线性筛去处理\mu,会直接Wa掉,因为没法处理到10^9次方那么大的前缀和,数组也开不了那么大。后果: H线μWa109

在这里插入图片描述
这 里 的 A C 可 能 就 是 一 小 部 分 的 运 气 罢 了 。 如 果 用 线 性 筛 , R E 的 R E , W A 的 W A , 所 以 推 荐 用 杜 教 筛 取 筛 。 这里的AC可能就是一小部分的运气罢了。如果用线性筛,RE的RE,WA的WA,所以推荐用杜教筛取筛。 AC线REREWAWA

设 f ( d ) = μ ( d ) , S ( r ) = ∑ d = 1 n f ( d ) , 这 里 的 S 就 是 要 求 的 前 缀 和 。 \blue{设f(d)=\mu(d),S(r)=\sum_{d=1}^nf(d),这里的S就是要求的前缀和。} f(d)=μ(d),S(r)=d=1nf(d)S
我 们 选 择 g = I , 则 ∑ i = 1 r ( f ∗ g ) i = ∑ i = 1 r ( μ ∗ I ) i = ∑ i = 1 r ε ( i ) = 1 。 我们选择\blue{g=I},则\sum_{i=1}^r(f*g)i=\sum_{i=1}^r(\mu*I)i=\sum_{i=1}^r\varepsilon (i)=1。 g=I,i=1r(fg)i=i=1r(μI)i=i=1rε(i)=1

枚 举 y : 枚举y: y

∑ y = 1 r g ( y ) ∑ x = 1 ⌊ r y ⌋ ) f ( x ) \sum_{y=1}^rg(y)\sum_{x=1}^{\left \lfloor \frac{r}{y} \right \rfloor)}f(x) y=1rg(y)x=1yr)f(x)

∑ y = 1 r g ( y ) S ( ⌊ r y ⌋ ) \sum_{y=1}^rg(y)S(\left \lfloor \frac{r}{y} \right \rfloor) y=1rg(y)S(yr)

∑ i = 1 r ( f ∗ g ) i = g ( 1 ) S ( r ) + ∑ y = 2 r g ( y ) S ( ⌊ r y ⌋ ) \sum_{i=1}^r(f*g)i =g(1)S(r)+\sum_{y=2}^rg(y)S(\left \lfloor \frac{r}{y} \right \rfloor) i=1r(fg)i=g(1)S(r)+y=2rg(y)S(yr)

S ( r ) = ∑ i = 1 r ( f ∗ g ) i − ∑ y = 2 r g ( y ) S ( ⌊ r y ⌋ ) g ( 1 ) S(r)=\frac{\sum_{i=1}^r(f*g)i-\sum_{y=2}^rg(y)S(\left \lfloor \frac{r}{y} \right \rfloor)}{g(1)} S(r)=g(1)i=1r(fg)iy=2rg(y)S(yr)

当 g = I 时 , 即 : 当g=I时,即: g=I

S ( r ) = 1 − ∑ y = 2 r S ( ⌊ r y ⌋ ) \red{S(r)=1-\sum_{y=2}^rS(\left \lfloor \frac{r}{y} \right \rfloor)} S(r)=1y=2rS(yr)

杜 教 筛 的 复 杂 度 为 O ( n 2 3 ) , 比 线 性 筛 还 要 快 一 点 , 总 时 间 复 杂 度 为 O ( n 2 3 ) 。 \red{杜教筛的复杂度为O(n\frac{2}{3}),比线性筛还要快一点,总时间复杂度为O(n^{\frac{2}{3}})。} O(n32)线O(n32)

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const ll mod = 1e9 + 7;

const int N = 1e6 + 10;

int mu[N]; // 莫比乌斯函数
bool is_prime[N];
int prime[N];
int cnt;
ll sum[N];

ll n, L, H, k;

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

void Mobi() // 莫比乌斯函数初始化
{
    
    
    mu[1] = 1;
    is_prime[0] = is_prime[1] = true;
    for(int i = 2;i < N; i++) {
    
    
        if (!is_prime[i]) {
    
    
            mu[i] = -1;
            prime[++cnt] = i;
        }
        for (int j = 1; j <= cnt && i * prime[j] < N; j++) {
    
    
            is_prime[i * prime[j]] = true;
            if (i % prime[j] == 0) {
    
    
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
    }
    for(int i = 1;i < N; i++) {
    
    
        sum[i] = (sum[i - 1] + mu[i]) % mod;
    }
}

map<ll , ll> mp;

ll Calc(ll x) {
    
    
    if(x < N)
        return sum[x];
    if(mp[x])
        return mp[x];
    ll num = 1;
    for(int l = 2, r;l <= x; l = r + 1) {
    
    
        r = x / (x / l);
        num = (num - Calc(x / l) * (r - l + 1) % mod + mod) % mod;
    }
    return mp[x] = num;
}

ll Ans() {
    
    
    ll ans = 0;
    for(ll l = 1, r;l <= H;l = r + 1) {
    
    
        r = min(H / (H / l), (L / l) ? L / (L / l) : H + 2);
        ans = (ans + (Calc(r) - Calc(l - 1) + mod) % mod * quick_pow((H / l) - (L / l), n) % mod + mod) % mod;
    }
    return (ans + mod) % mod;
}

void solve() {
    
    
    cin >> n >> k >> L >> H;
    L = (L - 1) / k; // 因为后面需要L-1,所以这里干脆就不+1了,但是含义不同
    H = H / k;
    Mobi();
    cout << Ans() << endl;
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

AT5200 [AGC038C] LCMs

求 解 ∑ i = 1 N ∑ j = 1 N l c m ( A i , A j ) 求解\sum_{i=1}^{N}\sum_{j=1}^Nlcm(A_i,A_j) i=1Nj=1Nlcm(Ai,Aj)

莫 比 乌 斯 反 演 处 理 的 一 般 都 是 枚 举 变 量 之 间 的 关 系 , 所 以 我 们 要 让 A i 和 A j 变 为 i 和 j 的 形 式 。 莫比乌斯反演处理的一般都是枚举变量之间的关系,所以我们要让A_i和A_j变为i和j的形式。 AiAjij

想 要 用 i 和 j 表 示 A i 和 A j 并 且 不 遗 漏 任 何 的 A , 所 以 让 A 等 于 某 个 i , 就 是 让 c n t i = ∑ d = 1 N [ A d = i ] , 统 计 所 有 A 等 于 某 个 i 的 个 数 , 即 c n t i , j 也 同 样 如 此 , 如 下 所 示 : 想要用i和j表示A_i和A_j并且不遗漏任何的A,所以让A等于某个i,就是让cnt_i=\blue{\sum_{d=1}^N[A_d=i]},统计所有A等于某个i的个数,即cnt_i,j也同样如此,如下所示: ijAiAjAAicnti=d=1N[Ad=i]Aicntij

∑ i = 1 N ∑ j = 1 N c n t i c n t j l c m ( i , j ) \sum_{i=1}^{N}\sum_{j=1}^Ncnt_icnt_jlcm(i,j) i=1Nj=1Ncnticntjlcm(i,j)

这 样 还 不 够 , 因 为 i 只 能 是 [ 1 , N ] 的 , 当 A i 中 有 些 值 大 于 N 的 话 , 再 枚 举 i 从 [ 1 , N ] 就 会 漏 掉 大 于 N 的 A i 的 情 况 , 所 以 想 要 统 计 所 有 情 况 , 即 让 N = A i 中 最 大 的 数 即 可 , 即 M = max ⁡ i = 1 N A i 。 这样还不够,因为i只能是[1,N]的,当Ai中有些值大于N的话,再枚举i从[1,N]就会漏掉大于N的Ai的情况,所以想要统计所有情况,即让N=Ai中最大的数即可,即\blue{M=\max_{i=1}^N { { A_i }}}。 i[1,N]AiNi[1,N]NAiN=AiM=maxi=1NAi
所 以 我 们 需 要 反 演 的 式 子 为 : 所以我们需要反演的式子为:

∑ i = 1 M ∑ j = 1 M c n t i ⋅ c n t j ⋅ l c m ( i , j ) \sum_{i=1}^{M}\sum_{j=1}^Mcnt_i ⋅cnt_j ⋅lcm(i,j) i=1Mj=1Mcnticntjlcm(i,j)

∑ i = 1 M ∑ j = 1 M c n t i ⋅ c n t j ⋅ i j g c d ( i , j ) \sum_{i=1}^{M}\sum_{j=1}^Mcnt_i ⋅cnt_j ⋅\frac{ij}{gcd(i,j)} i=1Mj=1Mcnticntjgcd(i,j)ij

∑ k = 1 M ∑ i = 1 M ∑ j = 1 M c n t i ⋅ c n t j ⋅ i j k [ g c d ( i , j ) = k ] \sum_{k=1}^M\sum_{i=1}^{M}\sum_{j=1}^Mcnt_i ⋅cnt_j ⋅\frac{ij}{k[gcd(i,j)=k]} k=1Mi=1Mj=1Mcnticntjk[gcd(i,j)=k]ij

∑ k = 1 M ∑ i = 1 ⌊ M k ⌋ ∑ j = 1 ⌊ M k ⌋ c n t i k ⋅ c n t j k ⋅ i j k 2 k [ g c d ( i , j ) = 1 ] \sum_{k=1}^M\sum_{i=1}^{\left \lfloor \frac{M}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{M}{k} \right \rfloor}cnt_{ik} ⋅cnt_{jk} ⋅\frac{ijk^2}{k}[gcd(i,j)=1] k=1Mi=1kMj=1kMcntikcntjkkijk2[gcd(i,j)=1]

∑ k = 1 M k ∑ i = 1 ⌊ M k ⌋ ∑ j = 1 ⌊ M k ⌋ c n t i k ⋅ c n t j k ⋅ i ⋅ j ∑ d ∣ i    d ∣ j μ ( d ) \sum_{k=1}^Mk\sum_{i=1}^{\left \lfloor \frac{M}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{M}{k} \right \rfloor}cnt_{ik} ⋅cnt_{jk} ⋅i ⋅j\sum_{d|i\;d|j}\mu(d) k=1Mki=1kMj=1kMcntikcntjkijdidjμ(d)

∑ k = 1 M k ∑ d = 1 ⌊ M k ⌋ μ ( d ) ∑ i = 1 ⌊ M k d ⌋ c n t i k d ⋅ i d ∑ j = 1 ⌊ M k d ⌋ c n t j k d ⋅ j d \sum_{k=1}^Mk\sum_{d=1}^{\left \lfloor \frac{M}{k} \right \rfloor}\mu(d)\sum_{i=1}^{\left \lfloor \frac{M}{kd} \right \rfloor}cnt_{ikd} ⋅id\sum_{j=1}^{\left \lfloor \frac{M}{kd} \right \rfloor}cnt_{jkd} ⋅jd k=1Mkd=1kMμ(d)i=1kdMcntikdidj=1kdMcntjkdjd

∑ k = 1 M k ∑ d = 1 ⌊ M k ⌋ μ ( d ) d 2 ( ∑ i = 1 ⌊ M k d ⌋ c n t i k d ⋅ i ) 2 \sum_{k=1}^Mk\sum_{d=1}^{\left \lfloor \frac{M}{k} \right \rfloor}\mu(d)d^2(\sum_{i=1}^{\left \lfloor \frac{M}{kd} \right \rfloor}cnt_{ikd} ⋅i)^2 k=1Mkd=1kMμ(d)d2(i=1kdMcntikdi)2

令 T = k d 则 : 令T=kd则: T=kd

∑ T = 1 M ( ∑ i = 1 ⌊ M T ⌋ c n t i T ⋅ i ) 2 ∑ k ∣ T μ ( k ) k 2 T k \sum_{T=1}^M(\sum_{i=1}^{\left \lfloor \frac{M}{T} \right \rfloor}cnt_{iT} ⋅i)^2\sum_{k|T}\mu(k)k^2\frac{T}{k} T=1M(i=1TMcntiTi)2kTμ(k)k2kT

∑ T = 1 M T ( ∑ i = 1 ⌊ M T ⌋ c n t i T ⋅ i ) 2 ∑ k ∣ T μ ( k ) k \sum_{T=1}^MT(\sum_{i=1}^{\left \lfloor \frac{M}{T} \right \rfloor}cnt_{iT} ⋅i)^2\sum_{k|T}\mu(k)k T=1MT(i=1TMcntiTi)2kTμ(k)k

令 f ( x ) = ∑ i ∣ x μ ( i ) i    ,    g ( x ) = ∑ i = 1 ⌊ M x ⌋ c n t i x ⋅ i = 1 x ∑ x ∣ t t c n t t , 则 最 后 的 式 子 为 : 令\blue{f(x)=\sum_{i|x}\mu(i)i\;,\;g(x)=\sum_{i=1}^{\left \lfloor \frac{M}{x} \right \rfloor}cnt_{ix} ⋅i=\frac{1}{x}\sum_{x|t}tcnt_t},则最后的式子为: f(x)=ixμ(i)i,g(x)=i=1xMcntixi=x1xttcntt,

∑ T = 1 M T g 2 ( T ) f ( T ) \sum_{T=1}^MTg^2(T)f(T) T=1MTg2(T)f(T)

O ( n ) 处 理 A 的 次 数 , O ( n l o g n ) 处 理 f 和 g , 总 时 间 复 杂 度 为 O ( n l o g n ) \red{O(n)处理A的次数,O(nlogn)处理f和g,总时间复杂度为O(nlogn)} O(n)AO(nlogn)fgO(nlogn)

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 5e5 + 10;

int mu[N]; // 莫比乌斯函数
bool is_prime[N];
int prime[N];
int tot;
ll f[N], g[N];

int M, n;
int cnt[N];

void Mobi() // 莫比乌斯函数初始化
{
    
    
    mu[1] = 1;
    is_prime[0] = is_prime[1] = true;
    for(int i = 2;i < N; i++) {
    
    
        if (!is_prime[i]) {
    
    
            mu[i] = -1;
            prime[++tot] = i;
        }
        for (int j = 1; j <= tot && i * prime[j] < N; j++) {
    
    
            is_prime[i * prime[j]] = true;
            if (i % prime[j] == 0) {
    
    
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
    }
    for(int i = 1;i <= M; i++) {
    
    
        for(int x = i;x <= M; x += i) {
    
    
            f[x] += mu[i] * i;
        }
    }

    for(int x = 1;x <= M; x++) {
    
    
        for(int t = x;t <= M; t += x) {
    
    
            g[x] += t * cnt[t];
        }
        g[x] /= x;
    }
}

void solve() {
    
    
    cin >> n;
    M = n;
    for(int i = 1;i <= n; i++) {
    
    
        int x;
        cin >> x;
        cnt[x]++;
        M = max(M, x);
    }
    Mobi();

    ll ans = 0;

    for(int i = 1;i <= M; i++) {
    
    
        ans += i * g[i] * g[i] * f[i];
    }

    cout << ans << endl;
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

SP5971 LCMSUM - LCM Sum

求 解 ∑ i = 1 n l c m ( i , n ) 求解\sum_{i=1}^nlcm(i,n) i=1nlcm(i,n)

⌊ n k ⌋ \left \lfloor \frac{n}{k} \right \rfloor kn

∑ i = 1 n i n g c d ( i , n ) \sum_{i=1}^n\frac{in}{gcd(i,n)} i=1ngcd(i,n)in

∑ k = 1 n ∑ i = 1 n i n k [ g c d ( i , n ) = k ] \sum_{k=1}^n\sum_{i=1}^n\frac{in}{k[gcd(i,n)=k]} k=1ni=1nk[gcd(i,n)=k]in

∑ k = 1 n ∑ i = 1 ⌊ n k ⌋ i n [ g c d ( i , n k ) = 1 ] \sum_{k=1}^n\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}in[gcd(i,\frac{n}{k})=1] k=1ni=1knin[gcd(i,kn)=1]

n ∑ k = 1 n ∑ i = 1 ⌊ n k ⌋ i [ g c d ( i , n k ) = 1 ] n\sum_{k=1}^n\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}i[gcd(i,\frac{n}{k})=1] nk=1ni=1kni[gcd(i,kn)=1]

n ∑ k ∣ n ∑ i = 1 k i [ g c d ( i , k ) = 1 ] n\sum_{k|n}\sum_{i=1}^ki[gcd(i,k)=1] nkni=1ki[gcd(i,k)=1]

n ∑ k ∣ n ∑ i = 1 k i ∑ d ∣ i    d ∣ k μ ( d ) n\sum_{k|n}\sum_{i=1}^ki\sum_{d|i\;d|k}\mu(d) nkni=1kididkμ(d)

枚 举 d : 枚举d: d

n ∑ k ∣ n ∑ d ∣ k μ ( d ) ∑ i = 1 ⌊ k d ⌋ i d n\sum_{k|n}\sum_{d|k}\mu(d)\sum_{i=1}^{\left \lfloor \frac{k}{d} \right \rfloor}id nkndkμ(d)i=1dkid

n ∑ k ∣ n ∑ d ∣ k μ ( d ) d ∑ i = 1 ⌊ k d ⌋ i n\sum_{k|n}\sum_{d|k}\mu(d)d\sum_{i=1}^{\left \lfloor \frac{k}{d} \right \rfloor}i nkndkμ(d)di=1dki

n ∑ k ∣ n ∑ d ∣ k μ ( d ) d ⌊ k d ⌋ ∗ ( ⌊ k d ⌋ + 1 ) 2 n\sum_{k|n}\sum_{d|k}\mu(d)d\frac{\left \lfloor \frac{k}{d} \right \rfloor*(\left \lfloor \frac{k}{d} \right \rfloor+1)}{2} nkndkμ(d)d2dk(dk+1)

n 2 ∑ k ∣ n { ∑ d ∣ k μ ( d ) ∗ k 2 d + ∑ d ∣ k μ ( d ) ∗ k } \frac{n}{2}\sum_{k|n}\{\sum_{d|k}\mu(d)*\frac{k^2}{d}+\sum_{d|k}\mu(d)*k\} 2nkn{ dkμ(d)dk2+dkμ(d)k}

n 2 ∑ k ∣ n k { ∑ d ∣ k μ ( d ) ∗ k d + ∑ d ∣ k μ ( d ) } \frac{n}{2}\sum_{k|n}k\{\sum_{d|k}\mu(d)*\frac{k}{d}+\sum_{d|k}\mu(d)\} 2nknk{ dkμ(d)dk+dkμ(d)}

这 时 候 发 现 两 个 狄 利 克 雷 卷 积 , φ ( n ) = μ ∗ i d = ∑ d ∣ n μ ( d ) ∗ n d      ,      ε ( n ) = μ ∗ I = ∑ d ∣ n μ ( d ) 。 所 以 我 们 将 其 替 换 得 : \blue{这时候发现两个狄利克雷卷积,\varphi (n)=\mu*id=\sum_{d|n}\mu(d)*\frac{n}{d}\;\;,\;\;\varepsilon(n) =\mu*I=\sum_{d|n}\mu(d)。所以我们将其替换得:} φ(n)=μid=dnμ(d)dn,ε(n)=μI=dnμ(d)

n 2 ∑ k ∣ n k [ φ ( k ) + ε ( k ) ] \frac{n}{2}\sum_{k|n}k[\varphi(k)+\varepsilon(k)] 2nknk[φ(k)+ε(k)]

O ( n ) 处 理 φ , n 询 问 答 案 , 总 复 杂 度 为 O ( n + T n ) 。 \red{O(n)处理\varphi,\sqrt n询问答案,总复杂度为O(n+T\sqrt n)。} O(n)φn O(n+Tn )

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 1e6 + 10;

int phi[N];
bool is_prime[N];
int prime[N];
int tot;

ll f[N];

void Euler()
{
    
    
    phi[1] = 1;
    is_prime[1] = true;
    for(int i = 2;i < N; i++){
    
    
        if(!is_prime[i]) {
    
    
            phi[i] = i - 1;
            prime[++tot] = i;
        }
        for(int j = 1;j <= tot && i * prime[j] < N; j++){
    
    
            is_prime[i * prime[j]] = true;
            if(i % prime[j]) {
    
    
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
            else{
    
    
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
        }
    }
    for(int i = 1;i < N; i++) {
    
    
        for(int j = i;j < N; j += i) {
    
    
            f[j]  += 1ll * phi[i] * i + (i == 1);
        }
    }
}

void solve() {
    
    
    Euler();
    int T;
    cin >> T;
    while(T--) {
    
    
        int n;
        cin >> n;
        cout << f[n] * n / 2 << endl;
    }
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

P5221 Product

求 解 ∏ i = 1 n ∏ j = 1 n l c m ( i , j ) g c d ( i , j ) 求解\prod_{i=1}^n\prod_{j=1}^n\frac{lcm(i,j)}{gcd(i,j)} i=1nj=1ngcd(i,j)lcm(i,j)

首 先 还 是 把 l c m ( i , j ) 化 简 得 : 首先还是把lcm(i,j)化简得: lcm(i,j)

∏ i = 1 n ∏ j = 1 n i j [ g c d ( i , j ) ] 2 \prod_{i=1}^n\prod_{j=1}^n\frac{ij}{[gcd(i,j)]^2} i=1nj=1n[gcd(i,j)]2ij

∏ i = 1 n ∏ j = 1 n i j ∗ ∏ i = 1 n ∏ j = 1 n 1 [ g c d ( i , j ) ] 2 \prod_{i=1}^n\prod_{j=1}^nij*\prod_{i=1}^n\prod_{j=1}^n\frac{1}{[gcd(i,j)]^2} i=1nj=1niji=1nj=1n[gcd(i,j)]21

我 们 很 容 易 推 出 前 半 部 分 的 数 值 为 ( n ! ) 2 n , 后 半 部 分 的 值 就 是 ∏ i = 1 n ∏ j = 1 n [ g c d ( i , j ) ] 2 的 逆 元 的 平 方 。 \blue{我们很容易推出前半部分的数值为(n!)^{2n },后半部分的值就是\prod_{i=1}^n\prod_{j=1}^n[gcd(i,j)]^2的逆元的平方。} (n!)2ni=1nj=1n[gcd(i,j)]2

所 以 现 在 求 解 : 所以现在求解:

∏ i = 1 n ∏ j = 1 n g c d ( i , j ) \prod_{i=1}^n\prod_{j=1}^ngcd(i,j) i=1nj=1ngcd(i,j)

∏ k = 1 n ∏ i = 1 n ∏ j = 1 n k [ g c d ( i , j ) = k ] \prod_{k=1}^n\prod_{i=1}^n\prod_{j=1}^nk[gcd(i,j)=k] k=1ni=1nj=1nk[gcd(i,j)=k]

∏ k = 1 n k ∑ i = 1 n ∑ j = 1 n [ g c d ( i , j ) = k ] \prod_{k=1}^nk^{\sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)=k]} k=1nki=1nj=1n[gcd(i,j)=k]

这 个 式 子 的 变 换 , 本 来 是 [ 1 , n ] 中 所 有 的 g c d 累 乘 , 然 后 我 们 单 独 把 g c d ( i , j ) = k 的 拿 出 来 , k 会 有 [ 1 , n ] 的 范 围 , 然 后 我 们 再 将 这 些 k 累 乘 就 会 达 到 之 前 的 效 果 。 这个式子的变换,本来是[1,n]中所有的gcd累乘,然后我们单独把gcd(i,j)=k的拿出来,k会有[1,n]的范围,然后我们再将这些k累乘就会达到之前的效果。 [1,n]gcdgcd(i,j)=kk[1,n]k
不 过 , [ 1 , n ] 中 的 g c d 不 单 单 只 有 一 个 , 可 能 会 有 多 个 相 同 的 g c d , 所 以 变 换 之 后 的 式 子 里 还 需 要 统 计 g c d = k 出 现 的 次 数 , 那 只 需 要 将 他 们 累 加 即 可 。 不过,[1,n]中的gcd不单单只有一个,可能会有多个相同的gcd,所以变换之后的式子里还需要统计gcd=k出现的次数,那只需要将他们累加即可。 [1,n]gcdgcdgcd=k

所 以 没 毛 病 。 继 续 : 所以没毛病。继续:

∏ k = 1 n k ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ n k ⌋ [ g c d ( i , j ) = 1 ] \prod_{k=1}^nk^{\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{n}{k} \right \rfloor}[gcd(i,j)=1]} k=1nki=1knj=1kn[gcd(i,j)=1]

∏ k = 1 n k ∑ i = 1 ⌊ n k ⌋ ∑ j = 1 ⌊ n k ⌋ ∑ d ∣ i    d ∣ j μ ( d ) \prod_{k=1}^nk^{\sum_{i=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\sum_{d|i\;d|j}\mu(d)} k=1nki=1knj=1kndidjμ(d)

枚 举 d : 枚举d: d

∏ k = 1 n k ∑ d = 1 ⌊ n k ⌋ μ ( d ) ∑ i = 1 ⌊ n k d ⌋ ∑ j = 1 ⌊ n k d ⌋ 1 \prod_{k=1}^nk^{\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\mu(d)\sum_{i=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}\sum_{j=1}^{\left \lfloor \frac{n}{kd} \right \rfloor}1} k=1nkd=1knμ(d)i=1kdnj=1kdn1

∏ k = 1 n k ∑ d = 1 ⌊ n k ⌋ μ ( d ) ( ⌊ n k d ⌋ ) 2 \red{\prod_{k=1}^nk^{\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\mu(d)(\left \lfloor \frac{n}{kd} \right \rfloor)^2}} k=1nkd=1knμ(d)(kdn)2

最 终 答 案 为 : 最终答案为:

( n ! ) 2 n ∏ k = 1 n k ∑ d = 1 ⌊ n k ⌋ μ ( d ) ( ⌊ n k d ⌋ ) 2 \red{(n!)^{2n}\prod_{k=1}^nk^{\sum_{d=1}^{\left \lfloor \frac{n}{k} \right \rfloor}\mu(d)(\left \lfloor \frac{n}{kd} \right \rfloor)^2}} (n!)2nk=1nkd=1knμ(d)(kdn)2

O ( n ) 处 理 μ 的 前 缀 和 , n 询 问 指 数 的 分 块 , 可 以 用 欧 拉 降 幂 优 化 , 总 时 间 复 杂 度 为 O ( n + n l o g 2 n \red{O(n)处理\mu的前缀和,\sqrt n询问指数的分块,可以用欧拉降幂优化,总时间复杂度为O(n+nlog_2n} O(n)μ,n O(n+nlog2n

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;

#define INF 0x7f7f7f
#define mem(a, b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)

// const ll mod = 998244353;
// const ll P = 1e9 + 7;
// const int maxn = 1e5 + 10;
// const double eps = 1e-6;

const int N = 1000010;
const ll mod = 104857601;

bool is_prime[N];
int prime[N];
int mu[N]; // 莫比乌斯函数
int cnt;

int n;
ll fac = 1;

ll quick_pow(ll a, ll b)
{
    
    
    ll ans = 1;
    while(b) {
    
    
        if(b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
void Mobi() // 莫比乌斯函数初始化
{
    
    
    mu[1] = 1;
    is_prime[0] = is_prime[1] = true;
    for(int i = 2;i <= n; i++) {
    
    
        if (!is_prime[i]) {
    
    
            mu[i] = -1;
            prime[++cnt] = i;
        }
        for (int j = 1; j <= cnt && i * prime[j] <= n; j++) {
    
    
            is_prime[i * prime[j]] = true;
            if (i % prime[j] == 0) {
    
    
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
        mu[i] = mu[i - 1] + mu[i];
        fac = fac * i % mod;
    }
}

ll Ans() {
    
    
    ll ans = 1;
    for(int k = 1;k <= n; k++) {
    
    
        ll p = 0;
        int t = n / k;
        for(int l = 1, r;l <= t; l = r + 1) {
    
    
            r = min(t, t / (t / l));
            p = (p + (mu[r] - mu[l - 1] + mod - 1) * (t / l) % (mod - 1) * (t / l) % (mod - 1)) % (mod - 1);
        }
        ans = ans * quick_pow(k, p) % mod;
    }
    ll k = quick_pow(ans, mod - 2);
    fac = quick_pow(fac, n);
    return quick_pow(k, 2) * fac % mod * fac % mod;
}

void solve() {
    
    
    cin >> n;
    Mobi();
    cout << Ans() << endl;
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    //cin.tie(nullptr);
    //cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
    
    
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}

HDU 6588 Function

求 解 ∑ i = 1 n g c d ( ⌊ i 3 ⌋ , i ) 求解\sum_{i=1}^ngcd(\left \lfloor \sqrt[3]i \right \rfloor,i) i=1ngcd(3i ,i)

我 们 先 将 这 个 一 重 和 式 转 化 为 二 重 和 式 , 得 : 我们先将这个一重和式转化为二重和式,得:

∑ a = 1 ⌊ n 3 ⌋ ∑ i = 1 n g c d ( a , i ) [ ⌊ i 3 ⌋ = a ] \sum_{a=1}^{\left \lfloor \sqrt[3]n \right \rfloor}\sum_{i=1}^ngcd(a,i)[\left \lfloor \sqrt[3]i \right \rfloor=a] a=13n i=1ngcd(a,i)[3i =a]

我 们 来 看 这 个 式 子 , 只 有 当 ⌊ i 3 ⌋ = a 时 , 才 会 有 对 答 案 的 贡 献 为 g c d ( a , i ) , 所 以 a ≤ ⌊ i 3 ⌋ < a + 1 , a 3 ≤ i ≤ ( a + 1 ) 3 − 1 , 所 以 上 式 转 化 为 : 我们来看这个式子,只有当\left \lfloor \sqrt[3]i \right \rfloor=a时,才会有对答案的贡献为gcd(a,i),所以\blue{a \leq \left \lfloor \sqrt[3]i \right \rfloor < a+1,a^3 \leq i \leq (a+1)^3-1},所以上式转化为: 3i =agcd(a,i)a3i <a+1a3i(a+1)31

∑ a = 1 ⌊ n 3 ⌋ ∑ i = a 3 m i n ( n , ( a + 1 ) 3 − 1 ) g c d ( a , i ) \red{\sum_{a=1}^{\left \lfloor \sqrt[3]n \right \rfloor}\sum_{i=a^3}^{min(n,(a+1)^3-1)}gcd(a,i)} a=13n i=a3min(n,(a+1)31)gcd(a,i)

然 后 我 们 将 这 个 二 重 和 式 拆 开 得 : 然后我们将这个二重和式拆开得:

∑ a = 1 ⌊ n 3 ⌋ − 1 ∑ i = a 3 m i n ( n , ( a + 1 ) 3 − 1 ) g c d ( a , i ) + ∑ i = ( ⌊ n 3 ⌋ ) 3 n g c d ( ⌊ n 3 ⌋ , i ) {\color{Brown}\sum_{a=1}^{\left \lfloor \sqrt[3]n \right \rfloor-1}\sum_{i=a^3}^{min(n,(a+1)^3-1)}gcd(a,i)+\sum_{i=(\left \lfloor \sqrt[3]n \right \rfloor)^3}^ngcd(\left \lfloor \sqrt[3]n \right \rfloor, i)} a=13n 1i=a3min(n,(a+1)31)gcd(a,i)+i=(3n )3ngcd(3n ,i)

令 n 3 = N , 并 使 a = i , i = j ( 好 看 一 点 ) 得 : 令\sqrt[3]n=N,并使a=i,i=j(好看一点)得: 3n =N使a=i,i=j

∑ i = 1 N − 1 ∑ j = i 3 ( i + 1 ) 3 − 1 g c d ( i , j ) + ∑ j = N 3 n g c d ( N , j ) {\color{Brown}\sum_{i=1}^{N-1}\sum_{j=i^3}^{(i+1)^3-1}gcd(i,j)+\sum_{j=N^3}^ngcd(N, j)} i=1N1j=i3(i+1)31gcd(i,j)+j=N3ngcd(N,j)

先 计 算 前 半 部 分 : 先计算前半部分:

$$$$

猜你喜欢

转载自blog.csdn.net/fztsilly/article/details/107919465