Powerful Number 筛学习笔记
Powerful Number 筛学习笔记
用途
\(Powerful\ number\) 筛可以用来求出一类积性函数的前缀和,最快可以达到根号复杂度。
实现
\(Powerful\ number\) 的定义是每个质因子次数都 \(\ge 2\) 的数。
有如下的性质:
\(1\)、一个 \(Powerful\ number\) 一定可以表示为 \(a^2b^3\) 的形式。
\(2\)、\(n\) 以内的 \(Powerful\ number\) 个数是 \(O(\sqrt n)\) 级别的。
所以找 \(Powerful\ number\) 可以直接暴力 \(dfs\)。
如果要求的函数是 \(f\),那么我们需要找到一个积性函数 \(g\),使得 \(f\) 和 \(g\) 在质数处的取值相同。
同时还要找到一个积性函数 \(h\),使得 \(f=g*h\)。
根据狄利克雷卷积的定义
\(f(p)=g(p)h(1)+g(1)h(p)=g(p)+h(p)=f(p)+h(p)\)。
所以 \(h(p)=0\),因为 \(h\) 是一个积性函数,所以所有非 \(Powerful\ number\) 在 \(h\) 函数中的取值都是 \(0\)。
\(\sum_{i=1}^nf(i)=\sum_{i=1}^n\sum_{d|i}h(d)g(\frac{i}{d})=\sum_{d=1}^nh(d)\sum_{j=1}^{\frac{n}{d}}g(j)\)。
因为 \(h\) 只在 \(Powerful\ number\) 处有值,所以我们只需要求出 \(\sqrt{n}\) 个 \(g\) 函数的前缀和即可。
例题
题目描述
给定一个积性函数 \(f\),满足 \(f(1)=1\),并且对于任意质数 \(p\) 和正整数 \(e\),都有 \(f(p^e)=p^k\),\(k\) 为给定的数,\(n \leq 10^{13},k \leq 20\)。
分析
构造积性函数 \(g\),满足对于任意 \(x\),都有 \(g(x)=x^k\)。
\(f(p^2)=g(p^2)h(1)+g(p)h(p)+g(1)h(p^2)\)。
那么 \(p^{k}=p^{2k}+h(p^2)\),\(h(p^2)=p^{k}-p^{2k}\)。
\(f(p^3)=g(p^3)h(1)+g(p^2)h(p)+g(p)h(p^2)+g(1)h(p^3)\)。
\(p^{k}=p^{3k}+p^k(p^{k}-p^{2k})+h(p^3)\),\(h(p^3)=p^{k}-p^{2k}\)。
多算几项就会发现 \(h(p^e)=p^{k}-p^{2k},e \ge 2\),
直接做就行了。
代码
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<map>
#define rg register
template<typename T>void read(rg T& x){
x=0;rg int fh=1;
rg char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
x*=fh;
}
const int maxn=1e7+5,maxm=35,mod=1e9+7;
inline int addmod(rg int now1,rg int now2){
return now1+=now2,now1>=mod?now1-mod:now1;
}
inline int delmod(rg int now1,rg int now2){
return now1-=now2,now1<0?now1+mod:now1;
}
inline int mulmod(rg long long now1,rg int now2){
return now1*=now2,now1>=mod?now1%mod:now1;
}
inline int ksm(rg int ds,rg int zs){
rg int nans=1;
while(zs){
if(zs&1) nans=mulmod(nans,ds);
ds=mulmod(ds,ds);
zs>>=1;
}
return nans;
}
int pri[maxn],k,sqr,b[maxm],c[maxm][maxm],ny[maxm],tot,val[maxn],mi[maxn],ans;
bool not_pri[maxn];
long long n,w[maxn];
void pre(){
for(rg int i=0;i<maxm;i++) c[i][0]=1;
for(rg int i=1;i<maxm;i++){
for(rg int j=1;j<=i;j++){
c[i][j]=addmod(c[i-1][j-1],c[i-1][j]);
}
}
ny[1]=1;
for(rg int i=2;i<maxm;i++) ny[i]=mulmod(mod-mod/i,ny[mod%i]);
b[0]=1;
for(rg int i=1;i<=20;i++){
for(rg int j=0;j<=i-1;j++){
b[i]=addmod(b[i],mulmod(c[i+1][j],b[j]));
}
b[i]=delmod(0,mulmod(b[i],ny[i+1]));
}
}
std::map<int,int> mp;
int getsum(rg int val){
if(mp.find(val)!=mp.end()) return mp[val];
val++;
rg int nans=0,tmp=val;
for(rg int i=k;i>=0;i--){
nans=addmod(nans,mulmod(c[k+1][i],mulmod(b[i],tmp)));
tmp=mulmod(tmp,val);
}
nans=mulmod(nans,ny[k+1]);
return mp[val-1]=nans;
}
void xxs(rg int mmax){
not_pri[0]=not_pri[1]=1;
for(rg int i=2;i<=mmax;i++){
if(!not_pri[i]){
pri[++pri[0]]=i;
mi[pri[0]]=delmod(ksm(i,k),ksm(i,k<<1));
}
for(rg int j=1;j<=pri[0] && i*pri[j]<=mmax;j++){
not_pri[i*pri[j]]=1;
if(i%pri[j]==0) break;
}
}
}
void dfs(rg int now,rg long long nw,rg int nval){
w[++tot]=nw,val[tot]=nval;
for(rg int i=now;i<=pri[0] && nw<=n/pri[i]/pri[i];i++){
rg long long tmp=1LL*nw*pri[i];
for(;tmp<=n/pri[i];tmp*=pri[i]) dfs(i+1,tmp*pri[i],mulmod(nval,mi[i]));
}
}
int main(){
pre();
read(n),read(k);
sqr=sqrt(n);
xxs(sqr+5);
dfs(1,1,1);
for(rg int i=1;i<=tot;i++){
ans=addmod(ans,mulmod(val[i],getsum((n/w[i])%mod)));
}
printf("%d\n",ans);
return 0;
}
Powerful Number 筛学习笔记的更多相关文章
- Min_25筛 学习笔记
这儿只是一个简单说明/概括/总结. 原理见这: https://www.cnblogs.com/cjyyb/p/9185093.html https://www.cnblogs.com/zhoushu ...
- $Min\_25$筛学习笔记
\(Min\_25\)筛学习笔记 这种神仙东西不写点东西一下就忘了QAQ 资料和代码出处 资料2 资料3 打死我也不承认参考了yyb的 \(Min\_25\)筛可以干嘛?下文中未特殊说明\(P\)均指 ...
- [笔记] Powerful Number 筛
定义 Powerful Number(以下简称 PN)筛类似于杜教筛,可以拿来求一些积性函数的前缀和. 要求: 假设现在要求积性函数 \(f\) 的前缀和 \(F(n)=\sum_{i=1}^nf(i ...
- Min_25 筛 学习笔记
原文链接https://www.cnblogs.com/zhouzhendong/p/Min-25.html 前置技能 埃氏筛法 整除分块(这里有提到) 本文概要 1. 问题模型 2. Min_25 ...
- 洲阁筛 & min_25筛学习笔记
洲阁筛 给定一个积性函数$F(n)$,求$\sum_{i = 1}^{n}F(n)$.并且$F(n)$满足在素数和素数次幂的时候易于计算. 显然有: $\sum_{i = 1}^{n} F(n) = ...
- Min_25筛学习笔记
感觉好好用啊 Luogu上的杜教筛模版题一发 Min_25抢到了 rank1 $ Updated \ on 11.29 $被 STO txc ORZ踩爆啦 前言 $ Min$_$25$筛可以求积性函数 ...
- min-25筛学习笔记
Min_25筛简介 \(\text{min_25}\)筛是一种处理一类积性函数前缀和的算法. 其中这类函数\(f(x)\)要满足\(\sum_{i=1}^{n}[i\in prime]\cdot f( ...
- min_25筛学习笔记【待填坑】
看见ntf和pb两位大佬都来学了,然后就不自觉的来学了. 我们考虑这样一个问题. $$ans=\sum_{i=1}^nf(i)$$其中$1\leq n\leq 10^{10}$ 其中$f(i)$是一个 ...
- 莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记
最近重新系统地学了下这几个知识点,以前没发现他们的联系,这次总结一下. 莫比乌斯反演入门:https://blog.csdn.net/litble/article/details/72804050 线 ...
随机推荐
- React tutorial
https://www.algolia.com Build Unique Search ExperiencesHosted Search API that delivers instant and r ...
- bash for mac
bash for mac https://sourabhbajaj.com/mac-setup/iTerm/ https://sourabhbajaj.com/mac-setup/iTerm/zsh. ...
- Frameworkless Movement
Frameworkless Movement 无框架运动 https://www.frameworklessmovement.org/ vanilla javascript https://githu ...
- github & code owners
github & code owners https://help.github.com/en/github/creating-cloning-and-archiving-repositori ...
- 官网GitLab CI/CD英文文档翻译
在查阅GitLab官网的CI/CD功能说明时,全是英文看起来不方便,通过翻译软件自动翻译后"内容失真",看起来很变扭.查阅了百度上的资料发现很多翻译很老旧,有些甚至是挂羊头卖狗肉. ...
- 正则表达式匹配${key}并在Java中使用
1.正则表达式匹配${key} \$\{([a-z]+)\} 能够匹配字符串中以${key}形式的文本(其中key为小写应为字母) .*\$\{([a-z]+)\}.* 可以用来检测文本中是否有${k ...
- Codeforces Global Round 13
比赛地址 A(水题) 题目链接 题目: 给出一个\(01\)序列,有2种操作:1.将某个位置取反:2.询问\(01\)序列中第\(k\)大的数 解析: 显然维护1的数目即可 #include<b ...
- HDOJ-4081(次小生成树+Prim算法)
Qin Shi Huang's National Road System HDOJ-4081 本题考查的是次小生成树的问题,这里的解决方法就是先使用Prim算法求解最小生成树. 在求解最小生成树的时候 ...
- MyBatis(一):JDBC使用存在的问题
JDBC使用步骤: a:加载 JDBC 驱动程序 b:创建数据库的连接对象Connection c:根据链接获取Statement d:拼接SQL语句及设置参数 e:执行SQL并获取结果集 f:关闭使 ...
- centos命令上传
首先安装 lrzsz # yum -y install lrzsz 运行 rz 命令: 在弹出的窗口选择需要上传的文件,文件会被上传至对应的目录下 运行 sz file.name 在弹出的窗口选择保存 ...