ICode9

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

线性筛法 & 洛谷P4449 于神之怒加强版

2022-05-17 00:35:06  阅读:192  来源: 互联网

标签:神之怒 洛谷 加强版 dfrac mid varphi times mu Longrightarrow


筛质数

基础的。

    // v 标记是否为合数,p 存储质数
    for (int i=2; i<=N; ++i) {
        v[i]||(p[++cnt]=i);
        for (int j=1,t; j<=cnt&&(t=p[j]*i)<=N; ++j) {
            v[t]=1;
            if (i%p[j]==0) break;
        }
    }

原理:每个合数 \(t\) 只被其最小质因子 \(p_j\) 筛一次。

设 \(i\) 的最小质因子为 \(p_{j_0}\)。
当 \(j\le j_0\) 时,\(p_j\) 是 \(t=p_j\times i\) 的最小质因子,因此用 \(p_j\) 筛掉 \(t\);
当 \(j>j_0\) 时,\(p_{j_0}\) 是 \(t\) 的最小质因子,不应再用 \(p_j\) 去筛,直接 break 掉就好了。

根据原理,上述筛法的时间复杂度是线性的,故称为线性筛。

筛欧拉函数 \(\varphi\)

  • 对于质数 \(i\):\(\varphi(i)=i-1\)。

  • 对于合数 \(t=p_j\times i\)(其中 \(p_j\) 为 \(t\) 的最小质因子):
    若 \(p_j\mid i\),则 \(\varphi(t)=p_j\times\varphi(i)\);
    若 \(p_j\nmid i\),则 \(\varphi(t)=\varphi(p_j)\times\varphi(i)\)。

    phi[1]=1;
    for (int i=2; i<=N; ++i) {
        v[i]||(p[++cnt]=i,phi[i]=i-1);
        for (int j=1; j<=cnt&&(t=p[j]*i)<=N; ++j) {
            v[t]=1;
            if (i%p[j]==0) { phi[t]=p[j]*phi[i]; break; }
            phi[t]=phi[p[j]]*phi[i];
        }
    }

筛莫比乌斯函数 \(\mu\)

同上,简单讨论一下即可。

  • \(i\in\mathbb P\Longrightarrow\mu(i)=-1\)。(用 \(\mathbb P\) 表示质数集)
  • \(p_j\mid i\Longrightarrow \mu(t)=0\);
    \(p_j\nmid i\Longrightarrow \mu(t)=\mu(p_j)\times\mu(i)=-\mu(i)\)。
    mu[1]=1;
    for (int i=2; i<=N; ++i) {
        v[i]||(p[++cnt]=i,mu[i]=-1);
        for (int j=1; j<=cnt&&(t=p[j]*i)<=N; ++j) {
            v[t]=1;
            if (i%p[j]==0) break;
            mu[t]=-mu[i];
        }
    }

筛因数个数 \(d\)

计算公式:设 \(n=\prod p_i^{k_i}\),则 \(d(n)=\prod(k_i+1)\)。
设 \(p_1\) 为最小质因子,令 \(f(n)=k_1+1\)。

  • \(i\in\mathbb P\Longrightarrow f(i)=2,d(i)=2\)。
  • \(p_j\mid i\Longrightarrow f(t)=f(i)+1,d(t)=\dfrac{d(i)f(t)}{f(i)}\);
    \(p_j\nmid i\Longrightarrow f(t)=2,d(t)=2d(i)\)。
    d[1]=1;
    for (int i=2; i<=N; ++i) {
        v[i]||(p[++cnt]=i,f[i]=2,d[i]=2);
        for (int j=1,t; j<=cnt&&(t=p[j]*i)<=N; ++j) {
            v[t]=1;
            if (i%p[j]==0) { f[t]=f[i]+1,d[t]=d[i]/f[i]*f[t]; break; }
            f[t]=2,d[t]=(d[i]<<1);
        }
    }

筛因数和 \(\sigma\)

计算公式:设 \(n=\prod p_i^{k_i}\),则 \(\sigma(n)=\prod(1+p_i+p_i^2+\cdots+p_i^{k_i})\)。
设 \(p_1\) 为最小质因子,令 \(g(n)=1+p_1+p_1^2+\cdots+p_1^{k_1}\)。

  • \(i\in\mathbb P\Longrightarrow g(i)=i+1,\sigma(i)=i+1\)。
  • \(p_j\mid i\Longrightarrow g(t)=p_j\times g(i)+1,f(t)=\dfrac{f(i)g(t)}{g(i)}\);
    \(p_j\nmid i\Longrightarrow g(t)=p_j+1,\sigma(t)=\sigma(p_j)\times\sigma(i)\)。
    s[1]=1;
    for (int i=2; i<=N; ++i) {
        v[i]||(p[++cnt]=i,g[i]=i+1,s[i]=i+1);
        for (int j=1,t; j<=cnt&&(t=p[j]*i)<=N; ++j) {
            v[t]=1;
            if (i%p[j]==0) { g[t]=p[j]*g[i]+1,s[t]=s[i]/g[i]*g[t]; break; }
            g[t]=p[j]+1,s[t]=s[p[j]]*s[i];
        }
    }

筛一般的积性函数

先鸽着,估计暂时也用不到。

筛 \(k\) 次幂

具体地说,给定 \(n,k,P\),求 \(1^k\sim n^k\) 的值,对 \(P\) 取模。

令 \(F(x)=x^k\),那么 \(F\) 是个积性函数,所以也可以线性筛。
但是对于质数 \(i\),我们只能做到用快速幂 \(O(\log k)\) 求出 \(i^k\bmod p\)。

\(n\) 以内的质数个数 \(\pi(n)\approx\dfrac n{\ln n}\),因此筛法的时间复杂度为 \(O\left(n+\dfrac{n\log k}{\ln n}\right)\)。


洛谷P4449 于神之怒加强版

给定 \(n,m,k\),计算

\[\sum_{i=1}^n\sum_{j=1}^m\gcd(i,j)^k \]

对 \(10^9+7\) 取模的结果。
每个测试点包含 \(T\) 组数据,它们共用相同的 \(k\)。

\(1\le T\le 2\times10^3,1\le n,m,k\le 5\times10^6.\)

推柿子的过程很常规,不写了,最后的结果是

\[\sum_{T=1}^{\min(n,m)}\left(\sum_{d\mid T}d^k\mu(\tfrac Td)\right)\left\lfloor\dfrac nT\right\rfloor\left\lfloor\dfrac mT\right\rfloor \]

关键在于括号里的部分怎么求。
理论上说,它是 \(f(x)=x^k\) 与 \(\mu\) 这两个积性函数的狄利克雷卷积,所以也是积性函数,应该可以用线性筛预处理。

设 \(g(n)=\sum\limits_{d\mid n}d^k\mu(\tfrac nd)\)。

对于 \(i\in\mathbb P\),显然有 \(g(i)=i^k-1\)。
对于合数 \(t\),设 \(t=p\times q\),其中 \(p\) 是 \(t\) 的最小质因子。
若 \(p\nmid q\),根据积性即可得到 \(g(t)=g(p)\times g(q)\)。
若 \(p\mid q\),我们可以得出 \(g(t)=p\times g(q)\)。推导过程留作习题。

至此可以用线性筛求 \(g\)。质数位置直接用快速幂计算。

时间复杂度 \(O\left(n+\dfrac{n\log k}{\ln n}+T\sqrt n\right)\)。

标签:神之怒,洛谷,加强版,dfrac,mid,varphi,times,mu,Longrightarrow
来源: https://www.cnblogs.com/REKonib/p/16230446.html

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

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

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

ICode9版权所有