下笔春蚕食叶声。

笔记:莫比乌斯反演

摘自peng-ym的博客

整除分块

\(\sum_{i=1}^n \lfloor {\frac n i} \rfloor\)

朴素 \(O(n)\) , 整除分块 \(O(\sqrt n)\)

显然有许多连续的 \(\lfloor {\frac n i} \rfloor\) 值是一样的。可以发现,每个块的最后一个数是 \(\frac n {\lfloor \frac n i\rfloor }\)

for(int l=1,r;l<=n;l=r+1){
    r=n/(n/l);
    ans+=(r-l+1)*(n/l);
}

有时推出的柿子不一定是裸的板子,可能与一些积性函数相乘( \(\mu\),\(\phi\)...),

此时需要对这些函数统计前缀和,这样跳过一个区间时就乘上一个区间的函数值。(?)

积性函数&狄利克雷卷积

%George1123

以后我也会卷啦!

积性函数:

定义:

如果 \(gcd(x,y)=1\) 并且 \(f(xy)=f(x)·f(y)\)\(f(n)\) 是积性函数。

特别的,对于任意 \(x,y\) 满足 \(f(xy)=f(x)·f(y)\) 的是完全积性函数。

e.g.

完全积性

  • 一元函数:\(\epsilon (x)=[x=1]\) 是积性函数的单位元(可以随便卷在一起和去掉)

  • 常数函数:\(1(x)=1\) 好像也有用字母 \(I\) 的。

  • 单位函数:\(id(x)=x\)

积性

  • 欧拉函数:\(\phi(x)=\sum_{i=1}^x [gcd(x,i)=1]\)

  • 约数个数函数:\(d(x)=\sum_{d|n} 1\)

  • 约数和函数: \(\sigma(n)=\sum_{d|n} d\)

  • 莫比乌斯函数:……

性质:

如果\(h(x)=f(x^p)\)\(h(x)=f^p(x)\)\(f(x)\) 是积性函数,那么 \(h(x)\) 也是:
如果 \(f(x)\)\(g(x)\) 是积性函数,那么 \(h(x)\) 也是:

\[h(x)=f(x)·g(x)\\ h(x)=\sum_{d|x} f(d)·g(\frac x d) \]

狄利克雷卷积

定义:

两个数论函数 \(f\)\(g\) 的狄利克雷卷积 \((f*g)\)

\[(f*g)(x)=\sum_{d|x} f(d)·g(\frac x d) \]

性质:

满足交换律和结合律和分配率。自己卷自己是自己。

莫比乌斯反演

莫比乌斯函数

  • 符号:\(\mu\) .

  • 定义:

    \[ \mu(d)=\left\{ \begin{array}{rcl} 1 & & {d=1}\\ (-1)^k & & {d=\Pi_{i=1}^k\ p_i\ 且\ p_i\ 为互异素数时}\\ 0 & & {d\ 的一个质因子次数\ge 2}\\ \end{array} \right. \]

  • 性质:

    1. 对于任意 \(n\in {N}^+\)\(\mu*1=\epsilon\ (\sum_{d|n} \mu(d)=[n=1])\) 常用性质

    考虑非0的 \(\mu(d)\) 的和。
    \(n\)\(k\) 个质因子,有 \(2^k\) 个因子,有 \(C_{k,i}\) 个的有 \(i\) 个质因子,
    \(ans=C(k,0)-C(k,1)+C(k,2)-C(k,3)+...=\sum_{i=0}^k (-1)^iC(k,i)\)
    二项式定理: \((x+y)^n=\sum C(n,i)x^iy^{(n-i)}\)
    \(ans=(-1+1)^k=0^k\)
    得证。

    \(\mu\)\(I\) 的狄利克雷逆

    1. 对于任意 \(n\in N^+\),

      \[\sum_{d|n} \frac {\mu(d)} d=\frac {\phi(n)} n \]

      Proof

      \[首先有结论\sum_{d|n} \phi(d)=n(id=\phi*I)\\ 证明:\\ \frac 1 n,\frac 2 n,\frac 3 n,...,\frac n n \\化简这些分数 分母是 d (d|n)\\ 每个分母d对应的分子个数就是 \phi(d) \]

      \[id=\phi*I\\ \phi=id*\mu\\ \phi(n)=\sum_{d|n} \mu(d)*\frac n d\\ \]

  • 代码

    void getmu(int n){
        mu[1]=1;
        for(int i=2;i<=n;i++){
            if(!vis[i]) { p[++cnt]=i; mu[i]=-1; }
            for(int j=1;j<=cnt&&p[j]*i<=n;j++){
                vis[p[j]*i]=1;
                if(i%p[j]==0) break;
                else mu[p[j]*i]=-mu[i];
            }
        }
    }
    

    \(O(n)\)

莫比乌斯反演

莫比乌斯反演定理

\(F(n)\)\(f(n)\) 是定义在 \(N\) 上的两个函数,并且满足条件

\[F(n)=\sum_{d|n} f(d) \]

有结论:

\[f(n)=\sum_{d|n} \mu(d)F(\lfloor {\frac n d} \rfloor) \]

Proof:

\[\sum_{d|n}\mu(d)F(\lfloor\frac{n}{d}\rfloor)\\=\sum_{d|n}\mu(d)\sum_{i|\lfloor\frac{n}{d}\rfloor}f(i)\\ =\sum_{i|n}f(i)\sum_{d|\lfloor\frac{n}{i}\rfloor}\mu(d)\\=f(n) \]

Proof2:

噫!好!让我们用狄利克雷卷积来证明一下。

已知

\[F(n)=\sum_{d|n} f(d) \]

求证

\[f(n)=\sum_{d|n} \mu(d)·F(\frac n d) \]

\[转化一下:\\ 已知:\\ F(n)=\sum_{d|n} f(d)\\ F(n)=\sum_{d|n} f(d)·1(\frac n d)\\ F=f*1\\ 求证:\\ f(n)=\sum_{d|n} \mu(d)·F(\frac n d)\\ f(n)=\mu *F\\ 证明:\\ F*\mu=f*1*\mu=f*\epsilon=f\\ 比上面那坨好多了qwq \]

莫比乌斯反演有另一种可能更好用的形式:

条件:

\[F(n)=\sum_{n|d} f(d) \]

结论:

\[f(n)=\sum_{n|d}\mu(\lfloor \frac{d}{n} \rfloor)F(d) \]

证明:
\(k=\frac d n\)

\(f(n)=\sum_{k=1}^{inf} \mu(k)F(nk)=\sum_{k=1}^{inf} \mu(k) \sum_{nk|t} f(t)=\sum_{n|t} f(t) \sum_{k|\frac t n} \mu(k)\)

当且仅当 \(\frac t n =1\) ,即 \(t=n\) 时, \(\sum_{k|\frac t n}\mu(k)=1\)

\(\sum_{n|t} f(t) \sum_{k|\frac t n}\mu (k)=f(n)\)


$F(n)=\sum_{n|d} f(d) $

\(f(n)=\sum_{n|d}\mu(\lfloor \frac{d}{n} \rfloor)F(d)\)

习题

LG2257 - YY的GCD

给定 \(N,M\) ,求 \(1\le x \le N,1\le y\le M\)\(gcd(x,y)\) 为质数的 \((x,y)\) 有多少对?

\(ans=\sum_{x=1}^n \sum_{y=1}^m [gcd(x,y)=prime]\)

第一道莫反不会做 列完这个柿子就壮烈牺牲了。

\(f(d)\)\(gcd(i,j)=d\) 的个数

\(F(n)\)\(gcd(i,j)=n\)\(n\) 的倍数的个数。

(套路)

\(f(d)=\sum_{x=1}^n \sum_{y=1}^m [gcd(x,y)=d]\)

\(F(n)=\sum_{n|d} f(d)=\lfloor \frac N n \rfloor \lfloor \frac M n \rfloor\)

\(f(n)=\sum_{n|d}\mu(\lfloor \frac{d}{n} \rfloor)F(d)\)

\(ans=\sum_{p\in prime} f(p)\)

\(ans=\sum_{p\in prime} \sum_{p|d}\mu(\lfloor \frac{d}{p} \rfloor)F(d)\)

\(ans=\sum_{p\in prime} \sum_{d=1}^{min(\frac n p,\frac m p)} \mu(d)F(dp)\)

\(ans=\sum_{p\in prime} \sum_{d=1}^{min(\frac n p,\frac m p)} \mu(d)\lfloor \frac n {dp} \rfloor \lfloor\frac m {dp} \rfloor\)

\(ans=\sum_{T=1}^{min(n,m)} \lfloor \frac n T \rfloor \lfloor \frac m T\rfloor \times(\sum_{t|T,t\in prime} \mu(\lfloor \frac T t\rfloor))\)

最后一坨东西可以预处理 前面那坨整除分块

void getmu(){
    mu[1]=1;
    for(int i=2;i<=N;i++){
        if(!fl[i]) p[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&p[j]*i<=N;j++){
            fl[p[j]*i]=1;
            if(i%p[j]==0) continue;
            mu[i*p[j]]=-mu[i];
        }
    }
    for(int i=1;i<=cnt;i++)
        for(int j=1;p[i]*j<=N;j++)
            f[p[i]*j]+=mu[j];//T=p[i]*j t=p[i]
    for(int i=1;i<=N;i++) sum[i]=sum[i-1]+f[i];
    return;
}//预处理前面那坨
long long solve(int a,int b){
    long long ans=0;
    for(int l=1,r;l<=a;l=r+1){
        r=min(a/(a/l),b/(b/l));
        ans+=1ll*(sum[r]-sum[l-1])*(a/l)*(b/l);
    }
    return ans;
}//预处理后面那坨
int main(){
    int t; scanf("%d",&t);
    getmu();
    while(t--){
        scanf("%d%d",&n,&m);
        if(n>m) swap(n,m);
        printf("%lld\n",solve(n,m));
    }
    return 0;
}

草,题解说入门的不适合做这题(

LG2522 - [HAOI2011]Problem b

\(n\) 次询问,每次询问有多少个数对 \((x,y)\) 满足 \(a\le x\le b,c\le y\le d\) 且 $gcd(x,y)=k $ 所有东西都是 \(5\times 10^4\)

草 这好像是前一题的低配啊,这确定没搞反吗。

\[\sum_{x=a}^b \sum_{y=c}^d [gcd(x,y)=k]\\ \sum_{x=1}^b \sum_{y=1}^d [gcd(x,y)=k]+\sum_{x=1}^a \sum_{y=1}^c [gcd(x,y)=k]-\sum_{x=1}^b \sum_{y=1}^c [gcd(x,y)=k]-\sum_{x=1}^a \sum_{y=1}^d [gcd(x,y)=k]\\ 即求\\ \sum_{x=1}^N \sum_{y=1}^M [gcd(x,y)=k]\\ 我们从上一题得到:\\ 设 f(d) 为 gcd(i,j)=d 的个数\\ F(n) 为 gcd(i,j)=n 和 n 的倍数的个数。\\ f(d)=\sum_{x=1}^n \sum_{y=1}^m [gcd(x,y)=d]\\ F(n)=\sum_{n|d} f(d)=\lfloor \frac N n \rfloor \lfloor \frac M n \rfloor\\ f(n)=\sum_{n|d}\mu(\lfloor \frac{d}{n} \rfloor)F(d)\\ f(n)=\sum_{n|d}\mu(\lfloor \frac{d}{n} \rfloor)\lfloor \frac N d \rfloor \lfloor \frac M d \rfloor\\ f(n)=\sum_{t=1}^{min(N,M)}\mu(t)\lfloor \frac N {nt} \rfloor \lfloor \frac M {nt} \rfloor\\ 然后求解前面那坨用预处理,后面那坨整除分块。 O(N+T\sqrt n) \]

void getmu(){
    mu[1]=1;
    for(int i=2;i<=N;i++){
        if(!fl[i]) p[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&p[j]*i<=N;j++){
            fl[p[j]*i]=1;
            if(i%p[j]==0) continue;
            mu[i*p[j]]=-mu[i];
        }
    }
    for(int i=1;i<=N;i++) sum[i]=sum[i-1]+mu[i];
    return;
}
long long solve(int a,int b,int k){
    if(a>b) swap(a,b);
    long long ans=0;
    for(int l=1,r;l<=a;l=r+1){
        r=min(a/(a/l),b/(b/l));
        ans+=1ll*(sum[r]-sum[l-1])*(a/(1ll*l*k))*(b/(1ll*l*k));
    }
    return ans;
}
int main(){
    int t; scanf("%d",&t);
    getmu();
    while(t--){
        int a,b,c,d,k;
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        printf("%lld\n",solve(b,d,k)-solve(a-1,d,k)-solve(b,c-1,k)+solve(a-1,c-1,k));
    }
    return 0;
}

显然顺序搞反了。。

[LG3455 - POI2007]ZAP-Queries

倒序开题,双倍经验,这是好的。这是前一道题的前置题。是 \(a=1,b=1\) 的情况。

[LG3327 - SDOI2015]约数个数和

\(d(x)\)\(x\) 的约数个数,给定 \(n,m\) ,求 \(\sum_{i=1}^n \sum_{j=1}^m d(ij)\)

\[ans=\sum_{i=1}^n \sum_{j=1}^m d(ij)=\sum_{i=1}^n \sum_{j=1}^m \sum_{x|i} \sum_{y|j} [gcd(x,y)=1]\\ 原因:gcd(x,y) 不为1时,x=ad,y=bd,xy=abd^2,在 x=ab,y=d^2时已被筛了一次。\\ ans=\sum_{i=1}^n \sum_{j=1}^m \sum_{x|i} \sum_{y|j} [gcd(x,y)=1]\\ =\sum_{x=1}^n \sum_{y=1}^m \lfloor \frac n x\rfloor \lfloor \frac m y \rfloor [gcd(x,y)=1]\\ =\sum_{i=1}^n \sum_{j=1}^m \lfloor \frac n i\rfloor \lfloor \frac m j \rfloor [gcd(i,j)=1]\\ 设 f(d)=\sum_{i=1}^n \sum_{j=1}^m \lfloor \frac n i\rfloor \lfloor \frac m j \rfloor [gcd(i,j)=d]\\ F(x)=\sum_{n|d} f(d)=\sum_{i=1}^n \sum_{j=1}^m \lfloor \frac n i\rfloor \lfloor \frac m j \rfloor [x|gcd(i,j)] =\sum_{i=1}^{\frac n x} \sum_{j=1}^{\frac m x} \lfloor \frac n {ix}\rfloor \lfloor \frac m {jx} \rfloor\\ \\ans=f(1)=\sum_{d=1}^{min(n,m)}\mu(d)F(d)=\sum_{x=1}^{min(n,m)} \mu(x) \sum_{i=1}^{\frac n x} \sum_{j=1}^{\frac m x} \lfloor \frac n {xi}\rfloor \lfloor \frac m {xj} \rfloor\\ 然后整除分块预处理 s(x)=\sum_{i=1}^x \lfloor \frac x i \rfloor \ \ O(1) 询问 F(d)\\ 这样可以O(T\sqrt n) \]

void init(){
    for(int i=1;i<=N;i++){
        for(int l=1,r;l<=i;l=r+1){
            r=i/(i/l);
            s[i]+=1ll*(r-l+1)*(i/l);
        }
    }//预处理s

    mu[1]=1;
    for(int i=2;i<=N;i++){
        if(!vis[i]) p[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&p[j]*i<=N;j++){
            vis[i*p[j]]=1;
            if(i%p[j]==0) continue;
            mu[i*p[j]]=-mu[i];
        }
    }
    for(int i=1;i<=N;i++) sum[i]=sum[i-1]+mu[i];
    return;
}
int main(){
    int t; scanf("%d",&t); 
    init();
    while(t--){
        int n,m; scanf("%d%d",&n,&m);
        if(n>m) swap(n,m);
        ll ans=0;
        for(int l=1,r;l<=n;l=r+1){
            r=min(n/(n/l),m/(m/l));
            ans+=1ll*(sum[r]-sum[l-1])*s[n/l]*s[m/l];
        }//分块求
        printf("%lld\n",ans);
    }
    return 0;
}

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

\(ans=\sum_{i=1}^n \sum_{j=1}^m lcm(i,j)\) \(n,m\le 10^7\)

\[\\ans=\sum_{i=1}^n \sum_{j=1}^m \frac {i\times j} {gcd(i,j)} \\=\sum_{d=1}^{min(n,m)} (d\times\sum_{i=1}^{\frac n d} \sum_{j=1}^{\frac m d} [gcd(i,j)=1]\times i\times j) \\∵\sum_{d|n} \mu(d)=[n=1] \\∴ ans=\sum_{d=1}^{min(n,m)} (d\times \sum_{i=1}^{\frac n d} \sum_{j=1}^{\frac m d} (\sum_{x|gcd(i,j)} \mu(x))\times i\times j ) \\\sum_{d=1}^{min(n,m)} d \times \sum_{x=1}^{min(\frac n d,\frac m d)} \mu(x) \sum_{i=1}^{\frac n d} \sum_{j=1}^{\frac m d} i\times j \times[x|gcd(i,j)] \\\sum_{d=1}^{min(n,m)} d\times \sum_{x=1}^{min(\frac n d,\frac m d)} \mu(x) \sum_{xu=1}^{\frac n d} \sum_{xv=1}^{\frac m d} x^2uv \\提出x^2 \\\sum_{d=1}^{min(n,m)} d\times \sum_{x=1}^{min(\frac n d,\frac m d)} \mu(x)x^2\sum_{xu=1}^{\frac n d} \sum_{xv=1}^{\frac m d} uv \\\sum_{d=1}^{min(n,m)} d\times \sum_{x=1}^{min(\frac n d,\frac m d)} \mu(x)x^2(\sum_{u=1}^{\frac n {dx}}u) \times (\sum_{v=1}^{\frac m {dx}} v)\\ \\\sum_{d=1}^{min(n,m)} d\times \sum_{x=1}^{min(\frac n d,\frac m d)} \mu(x)x^2 s(\frac n {dx}) \times s(\frac m {dx})\\ \\\mu(x)x^2 用前缀和优化,枚举d,整除分块求出后面一坨。 \\ 积分算出时间复杂度近似 O(n) 草不知道怎么搞的。 \]

void init(){
    mu[1]=1;
    for(int i=2;i<=N;i++){
        if(!vis[i]){ mu[i]=-1; p[++cnt]=i; }
        for(int j=1;j<=cnt&&p[j]*i<=N;j++){
            vis[p[j]*i]=1;
            if(i%p[j]==0) continue;
            mu[p[j]*i]=-mu[i];
        }
    }
    for(int i=1;i<=N;i++)
        sum[i]=(sum[i-1]+1ll*mu[i]%mod*i%mod*i%mod)%mod;
    return;
}
int calc(int x){ return (1ll*x*(x+1)/2)%mod; }
int main(){
    scanf("%d%d",&n,&m);
    if(n>m) swap(n,m);
    init();
    for(int d=1;d<=n;d++){
        int a=n/d,b=m/d,ret=0;
        for(int l=1,r;l<=a;l=r+1){
            r=min(a/(a/l),b/(b/l));
            ret=(ret+1ll*(sum[r]-sum[l-1])*calc(n/(d*l))%mod*calc(m/(d*l))%mod)%mod;
        }
        ans=(ans+1ll*ret*d%mod)%mod;
    }
    printf("%d\n",(ans+mod)%mod);
    return 0;
}

SP5971 LCMSUM - LCM Sum

\(T\) 次询问,每次询问给定 \(n\) ,求 \(\sum_{i=1}^n lcm(i,n)\)

\[\sum_{i=1}^n \frac {i\times n} {gcd(i,n)}\\ =n\sum_{i=1}^n \frac {i} {gcd(i,n)}\\ =n\sum_{d|n} \sum_{i=1}^n \frac {i} {d} [gcd(i,n)=d]\\ =n\sum_{d|n} \sum_{i=1}^{\frac n d} i·[gcd(i,\frac n d)=1]\\ \sum_{i=1}^{t} i·[gcd(i,t)=1] 表示[1,t]中与t互质的数的和。\\ 有结论t>1为 \frac {\phi(d)d} 2,d=1时为1(草我就不会这个) \\ 证明:d>1时,与d互质的数总是成对出现。(i与d互质,则d-i与d互质,和为d,有\frac {\phi(d)} 2 对。\\ ans=n\sum_{d|n} \frac {\phi(\frac n d)\frac n d} 2\\ 设f(d)=\sum_{d|n} \frac {\phi(\frac n d)\frac n d} 2\\ 对于每个 1\le d\le n 将\frac {\phi(d)·d} 2加入f(dj) 询问时再乘n \\复杂度O(T+n\log n) \]

void init(){
    phi[1]=1;
    for(int i=2;i<=N;i++){
        if(!vis[i]) phi[i]=i-1,p[++cnt]=i;
        for(int j=1;j<=cnt&&p[j]*i<=N;j++){
            vis[p[j]*i]=1;
            if(i%p[j]==0){
                phi[p[j]*i]=phi[i]*p[j];
                break;
            }
            phi[p[j]*i]=phi[i]*(p[j]-1);
        }
    }
    for(int i=1;i<=N;i++){
        ll tmp=1ll*phi[i]*i/2;
        if(i==1) tmp=1;
        for(int j=1;j*i<=N;j++) f[j*i]+=tmp;
    }
    return;
}
int main(){
    scanf("%d",&t);
    init();
    while(t--){
        scanf("%d",&n);
        printf("%lld\n",1ll*f[n]*n);
    }
    return 0;
}

咕咕咕

posted @ 2020-12-06 18:50  ACwisher  阅读(36)  评论(0编辑  收藏  举报