洛谷-4213 【模板】杜教筛(Sum)

题目描述
给定一个正整数N ( N ≤ 2 31 − 1 ) (N\le2^{31}-1) (N2311)

a n s 1 = ∑ i = 1 n φ ( i ) ans_1=\sum_{i=1}^n\varphi(i) ans1=i=1nφ(i)
a n s 2 = ∑ i = 1 n μ ( i ) ans_2=\sum_{i=1}^n \mu(i) ans2=i=1nμ(i)
输入格式
一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问
输出格式
一共T行,每行两个用空格分隔的数ans1,ans2

输入输出样例
输入 #1 复制
6
1
2
8
13
30
2333

输出 #1 复制
1 1
2 0
22 -2
58 -3
278 -3
1655470 2

以下是转的大佬的总结

积性函数
积性函数:对于任意互质的整数 a,ba,b 有 f(ab)=f(a)f(b) 则称 f(x)f(x) 的数论函数。
完全积性函数:对于任意整数 a,ba,b 有 f(ab)=f(a)f(b) 的数论函数。
常见的积性函数: φ , μ , σ , d \varphi,\mu,\sigma,d φ,μ,σ,d
常见的完全积性函数: ϵ , I , i d \epsilon,I,id ϵ,I,id
这里特殊解释一下 ϵ , I , i d \epsilon,I,id ϵ,I,id 分别是什么意思: ϵ ( n ) = [ n = 1 ] , I ( n ) = 1 , i d ( n ) = n \epsilon(n) = [n=1], I(n) = 1, id(n) = n ϵ(n)=[n=1],I(n)=1,id(n)=n
狄利克雷卷积
设 f, g 是两个数论函数,它们的狄利克雷卷积卷积是: ( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) (f*g)(n) = \sum \limits _{d | n} f(d) g(\frac{n}{d}) (fg)(n)=dnf(d)g(dn)
性质:满足交换律,结合律
单位元: ϵ ( 即 f ∗ ϵ = f ) \epsilon (即 f*\epsilon=f) ϵfϵ=f
结合狄利克雷卷积得到的几个性质:
μ ∗ I = ϵ \mu * I = \epsilon μI=ϵ
φ ∗ I = i d \varphi * I = id φI=id
μ ∗ i d = φ \mu * id = \varphi μid=φ
莫比乌斯反演

g ( n ) = ∑ d ∣ n f ( d ) g(n) = \sum\limits_{d|n}f(d) g(n)=dnf(d)

f ( n ) = ∑ d ∣ n μ ( d ) g ( n d ) f(n)=\sum\limits_{d|n}\mu(d)g(\frac{n}{d}) f(n)=dnμ(d)g(dn)
证明:这里需要用到前面提到的性质: μ ∗ I = ϵ \mu * I = \epsilon μI=ϵ
给出的条件等价于 g = f ∗ I g=f * I g=fI
所以 g ∗ μ = f ∗ I ∗ μ = f ∗ ϵ = f g*\mu=f*I*\mu=f*\epsilon=f gμ=fIμ=fϵ=f g ∗ μ = f g * \mu = f gμ=f即 结论。
杜教筛
设现在要求积性函数 ff 的前缀和, 设 ∑ i = 1 n f ( i ) = S ( n ) \sum \limits_{i=1}^{n} f(i) = S(n) i=1nf(i)=S(n)
再找一个积性函数 g ,则考虑它们的狄利克雷卷积的前缀和
∑ i = 1 n ( f ∗ g ) ( i ) \sum\limits_{i=1}^{n}(f*g)(i) i=1n(fg)(i)
= ∑ i = 1 n ∑ d ∣ i f ( d ) g ( i d ) = ∑ d = 1 n g ( d ) ∑ i = 1 ⌊ n d ⌋ f ( i ) = ∑ d = 1 n g ( d ) S ( ⌊ n d ⌋ ) \begin{aligned} &amp;= \sum\limits_{i=1}^{n} \sum \limits _{d|i} f(d)g(\frac{i}{d}) \\ &amp;= \sum \limits _{d=1}^{n} g(d)\sum\limits _{i=1}^{\lfloor \frac{n}{d}\rfloor } f(i) \\ &amp;= \sum \limits _{d=1}^{n} g(d) S(\lfloor \frac{n}{d} \rfloor) \end{aligned} =i=1ndif(d)g(di)=d=1ng(d)i=1dnf(i)=d=1ng(d)S(dn)
其中得到第一行是根据狄利克雷卷积的定义。
得到第二行则是先枚举 d 提出 g 。
得到第三行则是把 ∑ i = 1 ⌊ n d ⌋ f ( i ) \sum\limits _{i=1}^{\lfloor \frac{n}{d}\rfloor } f(i) i=1dnf(i)
​ f(i) 替换为 S ( ⌊ n d ⌋ ) S(\lfloor \frac{n}{d} \rfloor) S(dn)
接着考虑 g(1)S(n) 等于什么。
可以发现,他就等于
∑ i = 1 n g ( i ) S ( ⌊ n i ⌋ ) − ∑ i = 2 n g ( i ) S ( ⌊ n i ⌋ ) \sum \limits _{i=1}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor) i=1ng(i)S(in)i=2ng(i)S(in)
(可以理解成从1开始的前缀和减去从2开始的前缀和就是第一项)
前面这个式子 ∑ i = 1 n g ( i ) S ( ⌊ n i ⌋ ) \sum \limits _{i=1}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor) i=1ng(i)S(in)
根据刚才的推导,他就等于 ∑ i = 1 n ( f ∗ g ) ( i ) \sum\limits_{i=1}^{n}(f*g)(i) i=1n(fg)(i)
所以得到杜教筛的核心式子:
g ( 1 ) S ( n ) = ∑ i = 1 n ( f ∗ g ) ( i ) − ∑ i = 2 n g ( i ) S ( ⌊ n i ⌋ ) g(1)S(n)=\sum\limits_{i=1}^{n}(f*g)(i) - \sum \limits _{i=2}^{n} g(i) S(\lfloor \frac{n}{i} \rfloor) g(1)S(n)=i=1n(fg)(i)i=2ng(i)S(in)
得到这个式子之后有什么用呢?
现在如果可以找到一个合适的积性函数 g ,使得可以快速算出 ∑ i = 1 n ( f ∗ g ) ( i ) \sum\limits_{i=1}^{n}(f*g)(i) i=1n(fg)(i)
​ ( f ∗ g ) ( i ) ​(f∗g)(i) (fg)(i) 和 g 的前缀和,便可以用数论分块递归地求解。
( 1 ) μ (1) \mu (1)μ 的前缀和
考虑到莫比乌斯函数的性质 μ ∗ I = ϵ \mu * I = \epsilon μI=ϵ ,自然想到取 f = μ , g = I , f ∗ g = ϵ f=\mu,g=I,f*g=\epsilon f=μ,g=I,fg=ϵ
其中 I I I 的前缀和和 ϵ \epsilon ϵ 的前缀和都弱到爆了。。
( 2 ) (2) (2)考虑到 φ \varphi φ 的性质 φ ∗ I = i d \varphi * I = id φI=id,取 f = φ , g = I , f ∗ g = i d f = \varphi, g = I, f * g = id f=φ,g=I,fg=id
f ∗ g f * g fg 即 id 的前缀和为 n ∗ ( n + 1 ) 2 \frac{n * (n+1)}{2} 2n(n+1)
( 3 ) (3) (3) (综合) ∑ i = 1 n φ ( i ) ⋅ i \sum\limits_{i=1}^{n}\varphi(i) \cdot i i=1nφ(i)i
f = φ ⋅ i d , g = i d f = \varphi \cdot id, g = id f=φid,g=id, 考虑迪利克雷卷积的形式得到 ( f ∗ g ) ( n ) = ∑ d ∣ n ( φ ( d ) ⋅ d ) ⋅ ( n d ) = n ∑ d ∣ n φ ( d ) = n 2 (f*g)(n)=\sum \limits _{d|n} (\varphi(d) \cdot d) \cdot (\frac{n}{d}) = n \sum\limits_{d|n}\varphi(d)=n^2 (fg)(n)=dn(φ(d)d)(dn)=ndnφ(d)=n2
( f ∗ g ) ( i ) = i 2 (f * g)(i) = i^2 (fg)(i)=i2
这样就可以快速求得 ( f ∗ g ) ( i ) (f*g)(i) (fg)(i) 的前缀和 n ( n + 1 ) ( 2 n + 1 ) 6 \frac{n(n+1)(2n+1)}{6} 6n(n+1)(2n+1)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <tr1/unordered_map>
#define re register
using namespace std;
using namespace std::tr1;
inline int read() {
    int X=0,w=1; char c=getchar();
    while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
    while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar();
    return X*w;
}
typedef long long LL;
typedef unsigned long long ULL;
const int MAXN=5000000;
int v[MAXN+10];
int p[MAXN+10];
LL mu[MAXN+10],phi[MAXN+10];
inline void init() {
    v[1]=mu[1]=phi[1]=1;
    re int cnt=0;
    for (re int i=2;i<=MAXN;++i) {
        if (!v[i]) p[++cnt]=i,mu[i]=-1,phi[i]=i-1;
        for (re int j=1;j<=cnt&&i*p[j]<=MAXN;++j) {
            v[i*p[j]]=1;
            if (i%p[j]) mu[i*p[j]]=-mu[i],phi[i*p[j]]=phi[i]*phi[p[j]];
            else { mu[i*p[j]]=0,phi[i*p[j]]=phi[i]*p[j]; break; }
        }
    }
    for (re int i=1;i<=MAXN;++i) mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}
unordered_map<int,LL> ansmu,ansphi;
inline LL S_phi(int n) {
    if (n<=MAXN) return phi[n];
    if (ansphi[n]) return ansphi[n];
    LL ans=0;
    for (re int l=2,r;r<2147483647&&l<=n;l=r+1) //特判
        r=n/(n/l),ans+=(r-l+1)*S_phi(n/l);
    return ansphi[n]=(ULL)n*(n+1ll)/2ll-ans; //转ULL避免溢出
}
inline LL S_mu(int n){
    if (n<=MAXN) return mu[n];
    if (ansmu[n]) return ansmu[n];
    LL ans=0;
    for (re int l=2,r;r<2147483647&&l<=n;l=r+1) //同上
        r=n/(n/l),ans+=(r-l+1)*S_mu(n/l);
    return ansmu[n]=1ll-ans;
}
int main() {
    init();
    int T=read();
    while (T--) {
        int n=read();
        printf("%lld %lld\n",S_phi(n),S_mu(n));
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值