仅仅是 \(min25\) 筛最基本的方法,没有任何推式子的例题。(想了想还是加两道吧qwq)

这里解决的是 \(Luogu\) 那道模板题。

min25 基本方法:

最基础的是两个式子:

\[G(n,m): 所有合数 \space x \le n \space 的最小质因子 > pri_m 的 \space p^k 和或者是质数 \space x \le n \space 的\space p^k 的和。\\
G(n,m) = G(n,m - 1) - pri_m^k \times (G(\frac n{pri_m},m - 1) - G(pri_m - 1,m - 1))\\
S(n,m): 对于所有 \space x\le n\space 且最小质因数 > pri_m 的 p(x) 的和。\\
S(n,m) = G(n,cnt) - G(pri_m,cnt) + pri_i^e\times S(\frac n {pri_i^e},i)(i > m,pri_i^e \le n)
\]

用途: 求积性函数前缀和。

要求: \(f(p^k)\) (\(p\) 是质数)能够写成低阶多项式的形式。

时间: \(O(n^{1-\in})\) ,操过 \(10^{10}\) 不成问题。

怎么做:(\(pri\) 均表示合数的最小质因数,故必须满足 \(pri^2\le n\))(\(pri_k\) 表示第 \(k\) 个质数)

  1. 类似 \(dp\) 状态构造出 \(S(n,k)\) 表示所有小于等于 \(n\) 的质数,或者满足最小质因子大于\(pri_k\) 的合数所贡献的所有答案。
  2. 分为质数与合数统计答案,\(S(n,k) = G(k+1 \space to\space n [的质数贡献]) + f(pri_i^e) S(\frac n {pri_i^e},i)(i > k,pri_i^e\le n,pri_i^2\le n)\) 合数递归求解,质数提前与处理。
  3. 质数通过同样的方式,设 \(G(n,k)\) 表示前 \(n\) 个数最小质因子大于 \(pri_k\) 的合数或者是质数的单项式贡献。
  4. 因为我们最后仅仅关心 \(G(n,cnt)\) ,既所有质数的答案。所以我们仅需要计算 \(G(n)\) 即可。
  5. \(G(n,cnt) = G(n,cnt - 1) + pri_{cnt}^k G(\lfloor\frac n { pri_{cnt}}\rfloor,cnt - 1) (pri_{cnt}^2 \le n)\) 。因为 \(n\) 可能会很大,但因为整除的缘故,只需要保留 \(\sqrt n\) 个 \(G(n)\) 即可。
  6. 将最后没有被加上的 \(1\) 加上。

一些问题的探究:

Q: 积性函数这条性质到底用在了哪里?

A: 对于求 \(S\) 的板块,求合数的贡献时,本就将其的最小质因子分开来做了,这里需要 \(f\) 是一个积性函数。

​ 对于求 \(G\) 的板块,因为我们是将 \(p^k\) 的多项式拆开贡献求的,所以这里 \(G\) 维护的其实是一个完全积性函数的贡献,所以这里将其拆开做是对的。

Q: 为啥 \(f(p^k)\) 要求写成低阶多项式的形式?

A: \(G\) 就是这么构造的呀!假如说放在另外一个地方来看的话,我们要求 \(5^{233} + 4^{114514} + 3^{1919810} + 2 ^ {19260817}\) 的话,我们的 \(S\) 便是求总的答案的,而 \(G\) 是求得诸如 \(2^{19260817}\) 这样的单项式的。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 1e6 + 10,inv = 333333336;
const int Mod = 1e9 + 7;
ll n,m,sq;
ll sp1[N],sp2[N];
int pri[N],cnt = 0,vis[N];
ll g1[N],g2[N],val[N],tot;
ll Map1[N],Map2[N];
inline void Prime() {
for(int i = 2;i <= sq;i++) {
if(!vis[i]) {
pri[++cnt] = i;
sp1[cnt] = sp1[cnt - 1] + i;
sp2[cnt] = sp2[cnt - 1] + 1ll * i * i % Mod;
if(sp1[cnt] > Mod) sp1[cnt] -= Mod;
if(sp2[cnt] > Mod) sp2[cnt] -= Mod;
}
for(int j = 1;j <= cnt && 1ll * pri[j] * i <= sq ;j++) {
vis[pri[j] * i] = true;
if(i % pri[j] == 0) break;
}
}
}
inline ll S(ll now,int k) {
if(now <= pri[k]) return 0;
int loc = now <= sq ? Map1[now] : Map2[n / now];
ll res = g2[loc] - g1[loc] + sp1[k] - sp2[k] + Mod * 2,tem;
res %= Mod;
for(int i = k + 1;i <= cnt && 1ll * pri[i] * pri[i] <= now;i++) {//最小质因数 平方要小于等于原数
for(ll j = pri[i],total = 1;j <= now;total++,j *= pri[i]) {
tem = j % Mod;
res = res + tem * (tem - 1) % Mod * (S(now / j,i) + (total != 1)) % Mod; //注意细节,total 是用来计算所有f(p^k) 的值的,因为此时递归计算的最小质因数必须 > pri_i 所以不会计算到,所以要加上这一条。
if(res > Mod) res -= Mod;
}
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n;
sq = sqrt(n);
Prime();
for(ll l = 1,r;l <= n;l = r + 1) {//G(n,1)赋初值
r = (n / (n / l));
val[++tot] = n / l;
g1[tot] = val[tot] % Mod;
g2[tot] = g1[tot] * (g1[tot] + 1) / 2 % Mod * inv % Mod * (2 * g1[tot] + 1) % Mod;
g2[tot]--;
g1[tot] = g1[tot] * (g1[tot] + 1) / 2 % Mod - 1;
if(n / l <= sq) Map1[n / l] = tot;
else Map2[n / (n / l)] = tot;
if(g1[tot] < 0) g1[tot] += Mod;
if(g2[tot] < 0) g2[tot] += Mod;
}
for(int i = 1;i <= cnt;i++) {//算每一个可能会用到的 G(n,k)
for(int j = 1;j <= tot && 1ll * pri[i] * pri[i] <= val[j];j++) {//注意最小质因数 平方要小于等于原数
int k = (val[j] / pri[i] <= sq ? Map1[val[j] / pri[i]] : Map2[n / (val[j] / pri[i])]);
g1[j] = g1[j] - (g1[k] - sp1[i - 1]) * pri[i] % Mod;
g2[j] = g2[j] - (g2[k] - sp2[i - 1]) * pri[i] % Mod * pri[i] % Mod;
if(g1[j] < 0) g1[j] += Mod;
if(g2[j] < 0) g2[j] += Mod;
}
}
ll ans = S(n,0) + 1;
cout << (ans >= Mod ? ans - Mod : ans) << '\n';
return 0;
}

Min25 筛学习笔记的更多相关文章

  1. 莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记

    最近重新系统地学了下这几个知识点,以前没发现他们的联系,这次总结一下. 莫比乌斯反演入门:https://blog.csdn.net/litble/article/details/72804050 线 ...

  2. min25筛学习笔记

    min25筛简介:用来求积性函数F(x)前缀和的,复杂度O(n0.75/logn),大概能求n<=1010. 记一个数x的最小质因子为R(x),所以当x不为质数时,R(x)<=√x这是废话 ...

  3. min-25筛学习笔记

    Min_25筛简介 \(\text{min_25}\)筛是一种处理一类积性函数前缀和的算法. 其中这类函数\(f(x)\)要满足\(\sum_{i=1}^{n}[i\in prime]\cdot f( ...

  4. Min_25筛 学习笔记

    这儿只是一个简单说明/概括/总结. 原理见这: https://www.cnblogs.com/cjyyb/p/9185093.html https://www.cnblogs.com/zhoushu ...

  5. $Min\_25$筛学习笔记

    \(Min\_25\)筛学习笔记 这种神仙东西不写点东西一下就忘了QAQ 资料和代码出处 资料2 资料3 打死我也不承认参考了yyb的 \(Min\_25\)筛可以干嘛?下文中未特殊说明\(P\)均指 ...

  6. Powerful Number 筛学习笔记

    Powerful Number 筛学习笔记 用途 \(Powerful\ number\) 筛可以用来求出一类积性函数的前缀和,最快可以达到根号复杂度. 实现 \(Powerful\ number\) ...

  7. min25筛学习总结

    前言 杜教筛学了,顺便把min25筛也学了吧= =刚好多校也有一道题需要补. 下面推荐几篇博客,我之后写一点自己的理解就是了. 传送门1 传送门2 传送门3 这几篇写得都还是挺好的,接下来我就写下自己 ...

  8. 洲阁筛 & min_25筛学习笔记

    洲阁筛 给定一个积性函数$F(n)$,求$\sum_{i = 1}^{n}F(n)$.并且$F(n)$满足在素数和素数次幂的时候易于计算. 显然有: $\sum_{i = 1}^{n} F(n) = ...

  9. Min_25 筛 学习笔记

    原文链接https://www.cnblogs.com/zhouzhendong/p/Min-25.html 前置技能 埃氏筛法 整除分块(这里有提到) 本文概要 1. 问题模型 2. Min_25 ...

随机推荐

  1. Python+Selenium自动化-模拟键盘操作

    Python+Selenium自动化-模拟键盘操作   0.导入键盘类Keys() selenium中的Keys()类提供了大部分的键盘操作方法:通过send_keys()方法来模拟键盘上的按键. # ...

  2. Go语言协程并发---等待组sync.WaitGroup

    package main import ( "fmt" "sync" "time" ) /*等待组API介绍*/ func main071( ...

  3. Python+Selenium学习笔记11 - python官网的tutorial - 定义函数

    1 def f(a, L=[]): 2 L.append(a) 3 return L 4 5 print f(5) 6 print f(2) 输出 1 def f(a, L=None): 2 if L ...

  4. C ++基本输入/输出

    C ++基本输入/输出 本文将学习如何使用cin对象从用户那里获取输入,并使用cout对象在示例的帮助下向用户显示输出. C ++输出 在C ++中,cout将格式化的输出发送到标准输出设备,例如屏幕 ...

  5. CUDA C编程接口技术分析

    CUDA C编程接口技术分析 编程接口 CUDA C为熟悉C编程语言的用户提供了一个简单的路径,可以方便地编写程序供设备执行. 它由C语言的最小扩展集和运行库组成. 核心语言扩展已经引入:cuda c ...

  6. AIOps:企业运维新力量!

    摘要:企业运维需求及挑战,来看看华为AIOps如何解决! 本文分享自华为云社区<[云驻共创]AIOps?企业运维新力量!>,原文作者:启明. 国际惯例,我们先介绍一下AIOps的概念:AI ...

  7. 三、WPF入门教程——布局和常用Panel学习

    布局和常用Panel学习 一.简介 所有的WPF布局容器都派生自System.Windows.Controls.Panel.Panel继承自FrameworkElement. 在Panel中有一个比较 ...

  8. 卢卡斯定理&&中国剩余定理

    卢卡斯定理(模数较小,且是质数) 式子C(m,n)=C(m/p,n/p)*C(m%p,n%p)%p 至于证明(我也不会QAQ,只要记住公式也该就好了). 同时卢卡斯定理一般用于组合数取模上 1.首先当 ...

  9. [源码解析] 深度学习分布式训练框架 horovod (6) --- 后台线程架构

    [源码解析] 深度学习分布式训练框架 horovod (6) --- 后台线程架构 目录 [源码解析] 深度学习分布式训练框架 horovod (6) --- 后台线程架构 0x00 摘要 0x01 ...

  10. python读取txt文件绘制散点图

    方法和画折线图类似,差别在于画图函数不一样,用的是scatter() import matplotlib.pyplot as plt #以外部两个txt表分别作为x,y画图n=0m=0with ope ...