[luogu P5325][模板]Min_25筛

Posted cyf32768

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu P5325][模板]Min_25筛相关的知识,希望对你有一定的参考价值。

Address

Luogu #5325

Solution

  • (p_i) 表示第 (i) 小的质数((p[0]=1)),(s1[x]=sum_{i=1}^{x}p[x],s2[x]=sum_{i=1}^{x}p[x]^2)
  • (g1(x,i)) 为:[sum_{j=1}^{x}[j是质数或j的最小质因子大于p_i]j]
  • (g2(x,i)) 为:[sum_{j=1}^{x}[j是质数或j的最小质因子大于p_i]j^2]
  • 因为 (n) 以内的合数的最小质因子为 (O(sqrt n)),所以第二维的 (i) 满足:(p_i^2≤n)
  • (s(x,y)) 为:[sum_{j=1}^{x}[j的最小质因子大于p_y]j^2-j]
  • 那么显然有: [ans=S(x,y)+1]
  • 假设我们已经求得了所有的 (g1(x,i),g2(x,i))
  • 考虑如何求 (s(x,y))
  • 我们分别考虑质数与合数对答案的贡献。
  • 对于质数,记 (sqrt n) 以内的质数个数为 (c),我们要求的就是:[res=sum_{j=y+1}^{c}p_j^2-p_j]
  • 我们把它转换为两个前缀和相减的形式(前 (c) 个的贡献 (-)(j) 个的贡献),并且利用上 (g1,g2),那么有:[res=g2(x,c)-g1(x,c)-(s2[y]-s1[y])]
  • 对于合数,有最小质因子大于 (p_y) 的限制。
  • 我们枚举 (i,j),并计算所有满足以下条件的合数 (a) 对答案的贡献:
    1.(a) 的最小质因子为 (p_i)
    2.(a) 可以分解出 (j)(p_i)
  • 我们把每个合法的 (a) 都分解出因数 (p_i^j),记 (b) 为分解后的 (a),那么 (b) 要满足条件:
    1.(b) 的最小质因子大于 (p_i) (b=1)
    2.(b≤lfloorfrac{x}{p_i^j} floor)
  • 那么我们就得出了递推式:[s(x,y)=res-sum_{i=y+1}^{c}sum_{j=1,p_i^j≤x}f(p_i^j)*(s(lfloorfrac{x}{p_i^j} floor,i)+[j=1])]
  • 现在还有一个问题,就是求 (g1,g2)
  • 我们可以这样求 (g1)(g2) 同理):
  • 先让 (g1(x,i)=g1(x,i-1)),接着要减去所有满足最小质因子等于 (p_i)合数的贡献。
  • 我们还是把这些合数分解出因数 (p_i),然后分解后的数 (d) 要满足以下条件:
    1.(d) 的最小质因子大于 (p_{i-1})
    2.(d≤lfloorfrac{x}{p_i} floor)
  • 显然有:[g1(x,i)=g1(x,i-1)-p_i(g1(lfloorfrac{x}{p_i} floor,i-1)-s1[i-1])]
  • 然后还有一个问题就是 (g1,g2,s) 的第一维可能到 (O(n)) 级别,需要离散化。
  • 显然第一维只可能是某个 (lfloorfrac{n}{i} floor) 的值。
  • 那么当 (x≤sqrt n)时,记 (id1[x]) 表示 (x) 离散化后的值。
  • 否则,记 (id2[n/x]) 表示 (x) 离散化后的值。

Code

#include <bits/stdc++.h>

using namespace std;

#define ll long long

const int e = 1e6 + 5, mod = 1e9 + 7;
ll g1[e], g2[e], n, s1[e], s2[e], a[e];
bool bo[e];
int cnt, p[e], tot, id1[e], id2[e], s, inv6;

inline int plu(int x, int y)
{
    (x += y) >= mod && (x -= mod);
    return x;
}

inline int sub(int x, int y)
{
    (x -= y) < 0 && (x += mod);
    return x;
}

inline int ksm(int x, int y)
{
    int res = 1;
    while (y)
    {
        if (y & 1) res = (ll)res * x % mod;
        y >>= 1;
        x = (ll)x * x % mod;
    }
    return res;
}

inline int calc1(ll x)
{
    x %= mod;
    return (ll)x * (x + 1) / 2 % mod;
}

inline int calc2(ll x)
{
    x %= mod;
    return (ll)x * (x + 1) % mod * (2 * x + 1) % mod * inv6 % mod;
}

inline void init()
{
    inv6 = ksm(6, mod - 2); s = sqrt(n);
    ll i, j;
    for (i = 1; i <= n; i = j + 1)
    {
        a[++tot] = n / i;
        j = n / a[tot];
        g1[tot] = sub(calc1(a[tot]), 1);
        g2[tot] = sub(calc2(a[tot]), 1);
        if (a[tot] <= s) id1[a[tot]] = tot;
        else id2[n / a[tot]] = tot;
    }
}

inline void sieve()
{
    int i, j;
    for (i = 2; i <= s; i++)
    {
        if (!bo[i])
        {
            p[++cnt] = i;
            s1[cnt] = plu(s1[cnt - 1], i);
            s2[cnt] = plu(s2[cnt - 1], (ll)i * i % mod);
        }
        for (j = 1; j <= cnt && i * p[j] <= s; j++)
        {
            bo[i * p[j]] = 1;
            if (i % p[j] == 0) break;
        }
    }
}

inline void solve_g()
{
    int i, j;
    for (i = 1; i <= cnt; i++)
    {
        for (j = 1; j <= tot; j++)
        if ((ll)p[i] * p[i] <= a[j])
        {
            ll x = a[j], y = x / p[i];
            int k = y <= s ? id1[y] : id2[n / y], z = x <= s ? id1[x] : id2[n / x];
            g1[z] = sub(g1[z], (ll)p[i] * sub(g1[k], s1[i - 1]) % mod);
            g2[z] = sub(g2[z], (ll)p[i] * p[i] % mod * sub(g2[k], s2[i - 1]) % mod);
        }
    }
}

inline int dfs(ll x, int y)
{
    if (p[y] >= x) return 0;
    int i, j, k = x <= s ? id1[x] : id2[n / x];
    int res = sub(sub(g2[k], g1[k]), sub(s2[y], s1[y]));
    ll pj;
    for (i = y + 1; i <= cnt && (ll)p[i] * p[i] <= x; i++)
    for (j = 1, pj = p[i]; pj <= x; j++, pj = pj * p[i])
    {
        int f = pj % mod;
        f = (ll)f * sub(f, 1) % mod;
        res = plu(res, (ll)f * plu(dfs(x / pj, i), j != 1) % mod);
    }
    return res;
}

int main()
{
    cin >> n; init(); sieve(); solve_g();
    cout << plu(dfs(n, 0), 1) << endl;
    return 0;
}

以上是关于[luogu P5325][模板]Min_25筛的主要内容,如果未能解决你的问题,请参考以下文章

LG5325 模板Min_25筛

[模板]Min_25筛

P4213 模板杜教筛(Sum) min_25筛

Min_25

Min_25筛 学习小记

[Luogu#4707] 重返现世(min-max容斥+背包dp)