HDU 6750 Function-莫比乌斯反演进阶好题(一)

题目大意:

∑ i = 1 n ∑ t ∣ i t [ g c d ( t , i t ) = 1 ] \sum_{i=1}^{n}\sum_{t|i}^{}t[gcd(t,\frac it)=1] i=1ntit[gcd(t,ti)=1]
n ≤ 1 e 12 , T ≤ 10 n \leq 1e12,T \leq 10 n1e12,T10

题目思路:

这题在推导公式的时候有比较多的技巧需要使用.如下:

①换求和枚举顺序,消去整除符号:

= ∑ t = 1 n ∑ t ∣ i n t [ g c d ( t , i t ) = 1 ] =\sum_{t=1}^{n}\sum_{t|i}^{n}t[gcd(t,\frac it)=1] =t=1ntint[gcd(t,ti)=1]

= ∑ t = 1 n t ∑ i = 1 n t [ g c d ( t , i ) = 1 ] =\sum_{t=1}^{n}t\sum_{i=1}^{\frac nt}[gcd(t,i)=1] =t=1nti=1tn[gcd(t,i)=1]

= ∑ t = 1 n t ∑ i = 1 n t ∑ d ∣ g c d ( t , i ) μ ( d ) =\sum_{t=1}^{n}t\sum_{i=1}^{\frac nt}\sum_{d|gcd(t,i)}^{}\mu(d) =t=1nti=1tndgcd(t,i)μ(d)

②继续换求和枚举顺序,消去整除符号:

= ∑ d = 1 n μ ( d ) ∑ t = 1 n t ∑ i = 1 n t [ d ∣ g c d ( t , i ) ] =\sum_{d=1}^{n}\mu(d)\sum_{t=1}^{n}t\sum_{i=1}^{\frac nt}[d|gcd(t,i)] =d=1nμ(d)t=1nti=1tn[dgcd(t,i)]

∵ d ∣ g c d ( t , i ) ↔ d ∣ t ⋀ d ∣ i , 同 时 这 里 也 要 注 意 上 下 限 的 变 换 \because d|gcd(t,i) \leftrightarrow d|t\bigwedge d|i,同时这里也要注意上下限的变换 dgcd(t,i)dtdi,

= ∑ d = 1 n μ ( d ) ∑ t = 1 n d t d ∑ i = 1 n t d 2 1 =\sum_{d=1}^{n}\mu(d)\sum_{t=1}^{\frac nd}td\sum_{i=1}^{\frac{n}{td^2}}1 =d=1nμ(d)t=1dntdi=1td2n1

= ∑ d = 1 n μ ( d ) d ∑ t = 1 n d t ∑ i = 1 n t d 2 1 =\sum_{d=1}^{n}\mu(d)d\sum_{t=1}^{\frac nd}t\sum_{i=1}^{\frac{n}{td^2}}1 =d=1nμ(d)dt=1dnti=1td2n1

④令 T = t d 2 T=td^2 T=td2

= ∑ T = 1 n ∑ d = 1 n μ ( d ) d ∑ t = 1 n d t ∑ i = 1 n t d 2 [ T = t d 2 ] =\sum_{T=1}^{n}\sum_{d=1}^{n}\mu(d)d\sum_{t=1}^{\frac nd}t\sum_{i=1}^{\frac{n}{td^2}}[T=td^2] =T=1nd=1nμ(d)dt=1dnti=1td2n[T=td2]

∑ i = 1 n t d 2 \sum_{i=1}^{\frac{n}{td^2}} i=1td2n [ T = t d 2 ] [T=td^2] [T=td2]无关,转化成乘法:

= ∑ T = 1 n ⌊ n T ⌋ ∑ d = 1 n μ ( d ) d ∑ t = 1 n d t [ T = t d 2 ] =\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\sum_{d=1}^{n}\mu(d)d\sum_{t=1}^{\frac nd}t[T=td^2] =T=1nTnd=1nμ(d)dt=1dnt[T=td2]

⑥观察到 [ T = t d 2 ] [T=td^2] [T=td2],考虑枚举 d 2 d^2 d2的倍数

= ∑ T = 1 n ⌊ n T ⌋ ∑ d 2 ∣ T n μ ( d ) d ∑ t = 1 n d t [ T = t d 2 ] =\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\sum_{d^2|T}^{n}\mu(d)d\sum_{t=1}^{\frac nd}t[T=td^2] =T=1nTnd2Tnμ(d)dt=1dnt[T=td2]

⑦在已知 T T T d 2 d^2 d2的情况下, ∑ t = 1 n d t [ T = t d 2 ] \sum_{t=1}^{\frac nd}t[T=td^2] t=1dnt[T=td2]部分可转化为:

= ∑ T = 1 n ⌊ n T ⌋ ∑ d 2 ∣ T n μ ( d ) d ∑ t = 1 n d t [ t = T d 2 ] =\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\sum_{d^2|T}^{n}\mu(d)d\sum_{t=1}^{\frac nd}t[t=\frac{T}{d^2}] =T=1nTnd2Tnμ(d)dt=1dnt[t=d2T]

⑧观察: ∑ t = 1 n d t [ t = T d 2 ] \sum_{t=1}^{\frac nd}t[t=\frac{T}{d^2}] t=1dnt[t=d2T]

t ∈ [ 1 , n d ] , t\in[1,\frac nd], t[1,dn], n d ≥ T d ≥ T d 2 \frac nd\geq \frac{T}{d}\geq\frac T{d^2} dndTd2T

⑨所以 [ t = T d 2 ] [t=\frac{T}{d^2}] [t=d2T] t ∈ [ 1 , n d ] t\in[1, \frac nd] t[1,dn]必然成立且恰好只成立一次

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

⑩变换枚举顺序,消除整除符号:

= ∑ d = 1 n μ ( d ) ∑ T = 1 n ⌊ n T ⌋ [ d 2 ∣ T ] T d =\sum_{d=1}^{\sqrt n}\mu(d)\sum_{T=1}^{n}\lfloor\frac{n}{T}\rfloor[d^2|T]\frac{T}{d} =d=1n μ(d)T=1nTn[d2T]dT

(十一)从枚举 T T T改成枚举 k = T d 2 k=\frac T{d^2} k=d2T

= ∑ d = 1 n μ ( d ) ∑ k = 1 ⌊ n d 2 ⌋ ⌊ n k d 2 ⌋ k d 2 d =\sum_{d=1}^{\sqrt n}\mu(d)\sum_{k=1}^{\lfloor\frac n{d^2}\rfloor}\lfloor\frac{n}{kd^2}\rfloor\frac{kd^2}{d} =d=1n μ(d)k=1d2nkd2ndkd2

= ∑ d = 1 n μ ( d ) d ∑ k = 1 ⌊ n d 2 ⌋ ⌊ ⌊ n d 2 ⌋ k ⌋ k =\sum_{d=1}^{\sqrt n}\mu(d)d\sum_{k=1}^{\lfloor\frac n{d^2}\rfloor}\lfloor\frac{\lfloor \frac n{d^2}\rfloor}{k}\rfloor k =d=1n μ(d)dk=1d2nkd2nk

(十二)令 F ( n ) = ∑ i = 1 n i ∗ ⌊ n i ⌋ F(n)=\sum_{i=1}^{n}i * \lfloor \frac {n}{i} \rfloor F(n)=i=1niin

原 式 = ∑ d = 1 n μ ( d ) ∗ d ∗ F ( ⌊ n d 2 ⌋ ) 原式=\sum_{d=1}^{\sqrt n}\mu(d)*d*F(\lfloor \frac n{d^2}\rfloor) =d=1n μ(d)dF(d2n)

复杂度分析:

外层直接枚举 n \sqrt n n 次, F ( i ) F(i) F(i)复杂度为: i \sqrt i i

所以复杂度可以写成以下和式:
∑ i = 1 n n i 2 = ∑ i = 1 n n i = n l o g n \sum_{i=1}^{\sqrt n}\sqrt{\frac {n}{i^2}}=\sum_{i=1}^{\sqrt n}\frac{\sqrt{n}}{i}=\sqrt n log{\sqrt n} i=1n i2n =i=1n in =n logn


细节补充:

形如: ∑ d = 1 n g ( d ) ∗ f ( ⌊ n d 2 ⌋ ) \sum_{d=1}^{n}g(d)*f(\lfloor \frac n{d^2}\rfloor) d=1ng(d)f(d2n)的式子如何整除分块?

直接套用整除分块的定义: r 2 = ⌊ n ⌊ n l 2 ⌋ ⌋ r^2=\lfloor \frac{n}{\lfloor \frac{n}{l^2} \rfloor}\rfloor r2=l2nn

r = ⌊ n ⌊ n l 2 ⌋ ⌋ r=\sqrt{\lfloor \frac{n}{\lfloor \frac{n}{l^2} \rfloor}\rfloor} r=l2nn

进一步优化

由于这题的常数很大,可能会 T T T。尝试从以下几个方面来考虑优化:

一.利用细节补充我们可以将外层的循环转化成一个数论分块。那么问题就变成了数论分块套数论分块。

二. F F F函数输出只和输入有关,可以记忆化一下.

三.考虑预处理 F F F函数:

推导:
F ( n ) = ∑ i = 1 n i ∗ ⌊ n i ⌋ = ∑ i = 1 n i ∗ ∑ i ∣ j n 1 = ∑ j = 1 n ∑ i ∣ j i = ∑ j = 1 n σ ( j ) F(n)=\sum_{i=1}^{n}i * \lfloor \frac {n}{i} \rfloor=\sum_{i=1}^{n}i * \sum_{i|j}^{n}1=\sum_{j=1}^{n}\sum_{i|j}^{}i=\sum_{j=1}^{n}\sigma(j) F(n)=i=1niin=i=1niijn1=j=1niji=j=1nσ(j)

所以 F ( n ) F(n) F(n)为约数和的 n n n项前缀和.可以上筛法

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define vll vector<ll>
#define fi first
#define se second
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
int u[maxn] , bk[maxn] , p[maxn] , cnt;
ll sum[maxn];
ll g[maxn];
void init ()
{
    u[1] = 1;
    for (int i = 2 ; i < maxn ; i++){
        if (!bk[i]){
            p[++cnt] = i;
            u[i] = -1;
        }
        for (int j = 1 ; j <= cnt && i * p[j] < maxn ; j++){
            bk[i * p[j]] = 1;
            if (i % p[j] == 0) {
                u[i * p[j]] = 0;
                break;
            }else {
                u[i * p[j]] = -u[i];
            }
        }
    }
    for (int i = 1 ; i < maxn ; i++){
        for (int j = i ; j < maxn ; j += i){
            g[j] = (g[j] + i) % mod;
        }
    }
    for (int i = 1 ; i < maxn ; i++){
        sum[i] = (sum[i - 1] + 1ll * (u[i] + mod) % mod * i % mod) % mod;
        g[i] = (g[i - 1] + g[i]) % mod;
    }
    return ;
}
ll ksm (ll a , ll b){ ll ans = 1 , base = a;
while (b){if (b & 1) ans = ans * base % mod;b >>= 1;base = base * base % mod;}return ans;}
ll inv2 = ksm(2 , mod - 2);
unordered_map<ll , ll> dp;
ll F (ll n){
    //if (n < maxn) return g[n];
    if ( dp.count(n) ) return dp[n];
    ll ans = 0;
    ll x , y , z;
    for (ll l = 1 , r; l <= n ; l = r + 1){
        r = n / (n / l);
        x = (r - l + 1) % mod;
        y = (l + r) % mod;
        z = (n / l) % mod;
        ll a = x * y % mod;
        a = a * inv2 % mod;
        a = a * z % mod;
        ans = (ans + a) %mod;
    }
    return dp[n] = ans;
}
int main()
{
    ios::sync_with_stdio(false);
    init();
    int t; cin >> t;
    dp.clear();
    while (t--){
        ll n; cin >> n;
        ll ans = 0;
        ll m = sqrt(n);
        ll x;
        for (ll l = 1 , r; l <= m ; l = r + 1){
            x = n / l / l;
            r = min((ll)sqrt(n / x) , m);
            ll res = (sum[r] - sum[l - 1] + mod) %mod;
            res = res * F(x) % mod;
            ans = (ans + res) % mod;
        }
        cout << ans << endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值