min_25筛题目总结
看了网上众多博客后,我才发现,实现min_25只有脑子,没有代码。
当然可能是我太ruo了。
min_25是一种想法,不是算法。
不要尝试套模板,因为很多题目并没有什么用。
最重要的一点,g不要看成是函数,而是埃式筛第j轮后的剩下的数的F之和;S看成dp来做,也不要记忆化。
1.求[1,n]中素数个数。n≤1E11
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll maxn=1E6+;
ll n,prime[maxn],size,sqr,back[maxn],m,g[maxn],id1[maxn],id2[maxn];
bool vis[maxn];
void init(ll n)
{
for(int i=;i<=n;++i)
{
if(!vis[i])prime[++size]=i;
for(int j=;j<=size&&i*prime[j]<=n;++j)
{
vis[i*prime[j]]=;
if(i%prime[j]==)break;
}
}
}
void put(ll x,int y)
{
if(x<=sqr)id1[x]=y;
else id2[n/x]=y;
}
int where(ll x)
{
if(x<=sqr)return id1[x];
else return id2[n/x];
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
sqr=sqrt(n)+;
init(sqr);
for(ll i=,j;i<=n;i=j+)
{
back[++m]=n/i;
j=n/back[m];
put(n/i,m);
g[m]=back[m]-;
}
for(int j=;j<=size;++j)
{
ll limit=prime[j]*prime[j];
for(int i=;back[i]>=limit;++i)
{
int k=where(back[i]/prime[j]);
g[i]+=j--g[k];
}
}
cout<<g[]<<endl;
return ;
}
2.求[1,n]中素数个数和。n≤1E11
#include<bits/stdc++.h>
#define mod 1000000007
#define G 500000004
using namespace std;
typedef long long int ll;
const ll maxn=1E6+;
ll prime[maxn],size,id1[maxn],id2[maxn],m,n,back[maxn],sumF[maxn],sqr,g[maxn];
bool vis[maxn];
void put(ll x,ll y)
{
if(x<=sqr)id1[x]=y;
else id2[n/x]=y;
}
ll where(ll x)
{
if(x<=sqr)return id1[x];
else return id2[n/x];
}
ll sum(ll n)
{
return (n*(n+)%mod*G-+mod)%mod;
}
void init(int n)
{
for(int i=;i<=n;++i)
{
if(!vis[i])prime[++size]=i,sumF[size]=(sumF[size-]+i)%mod;
for(int j=;j<=size&&i*prime[j]<=n;++j)
{
vis[i*prime[j]]=;
if(i%prime[j]==)break;
}
}
}
void calc()
{
for(int j=;j<=size;++j)
{
ll limit=prime[j]*prime[j];
for(int i=;back[i]>=limit;++i)
{
int k=where(back[i]/prime[j]);
g[i]=(g[i]-prime[j]*(g[k]-sumF[j-])%mod+mod)%mod;
}
}
}
void make()
{
for(ll i=,j;i<=n;i=j+)
{
back[++m]=n/i;
j=n/back[m];
put(n/i,m);
g[m]=sum(n/i);
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
sqr=sqrt(n)+;
init(sqr);
make();
calc();
cout<<g[]<<endl;
return ;
}
3.loj6053(目前不知为何会爆long long,也许是其他原因?)
#include<bits/stdc++.h>
#define mod 1000000007
#define G 500000004
using namespace std;
typedef long long int ll;
const ll maxn=1E6+;
ll g1[maxn],g2[maxn],back[maxn],id1[maxn],id2[maxn],n,m,sqr,size,prime[maxn],sumPrime[maxn];
bool vis[maxn];
void init(ll n)
{
for(ll i=;i<=n;++i)
{
if(!vis[i])prime[++size]=i,sumPrime[size]=(sumPrime[size-]+i)%mod;
for(ll j=;j<=size&&prime[j]*i<=n;++j)
{
vis[prime[j]*i]=;
if(i%prime[j]==)break;
}
}
}
void put(ll x,ll y)
{
if(x<=sqr)id1[x]=y;
else id2[n/x]=y;
}
ll where(ll x)
{
if(x<=sqr)return id1[x];
else return id2[n/x];
}
ll sum2(ll n){return ((n+)*n%mod*G%mod-+mod)%mod;}
void make()
{
for(ll i=,j;i<=n;i=j+)
{
back[++m]=n/i;
j=n/back[m];
put(n/i,m);
g1[m]=(back[m]-+mod)%mod;
g2[m]=sum2(back[m]);
}
}
void calc1()
{
for(ll j=;j<=size;++j)
{
ll limit=prime[j]*prime[j];
for(ll i=;back[i]>=limit;++i)
{
ll k=where(back[i]/prime[j]);
g1[i]=(g1[i]-g1[k]+j-+mod)%mod;
}
}
}
void calc2()
{
for(ll j=;j<=size;++j)
{
ll limit=prime[j]*prime[j];
for(ll i=;back[i]>=limit;++i)
{
ll k=where(back[i]/prime[j]);
g2[i]=(g2[i]-prime[j]*(((g2[k]-sumPrime[j-])%mod+mod)%mod)%mod+mod)%mod;
}
}
}
ll S(ll n,ll j)
{
ll k,sum=;
if(n<=||prime[j]>n)return ;
k=where(n);
sum=(g2[k]-sumPrime[j-]-g1[k]+j-+mod)%mod;
if(j==)sum=(sum+)%mod;
for(ll i=j;i<=size&&prime[i]*prime[i]<=n;++i)
for(ll e=,s=prime[i]*prime[i];s<=n;s*=prime[i],++e)
(sum+=(prime[i]^e)*S(n*prime[i]/s,i+)%mod+(prime[i]^(e+))%mod)%=mod;
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
if(n==){cout<<<<endl;return ;}
if(n==){cout<<<<endl;return ;}
sqr=sqrt(n)+;
init(sqr);
make();
calc1();
calc2();
cout<<(S(n,)+)%mod;
return ;
}
4.求[1,n]中phi的和。保证结果不超过long long。
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll maxn=1E6+;
ll back[maxn],id1[maxn],id2[maxn],n,m,size,prime[maxn],sqr,sumPrime[maxn];
ll g1[maxn],g2[maxn];
bool vis[maxn];
void put(ll x,ll y)
{
if(x<=sqr)id1[x]=y;
else id2[n/x]=y;
}
ll where(ll x)
{
if(x<=sqr)return id1[x];
else return id2[n/x];
}
void init(ll s)
{
for(int i=;i<=s;++i)
{
if(!vis[i])prime[++size]=i,sumPrime[size]=sumPrime[size-]+i;
for(int j=;j<=size&&prime[j]*i<=s;++j)
{
vis[prime[j]*i]=;
if(i%prime[j]==)break;
}
}
for(ll i=,j;i<=n;i=j+)
{
back[++m]=n/i;
j=n/back[m];
put(n/i,m);
g1[m]=n/i-;
g2[m]=(back[m]+)*back[m]/-;
}
}
void calc1()
{
for(int j=;j<=size;++j)
{
ll limit=prime[j]*prime[j];
for(int i=;back[i]>=limit;++i)
{
int k=where(back[i]/prime[j]);
g1[i]-=g1[k]-j+;
}
}
}
void calc2()
{
for(int j=;j<=size;++j)
{
ll limit=prime[j]*prime[j];
for(int i=;back[i]>=limit;++i)
{
int k=where(back[i]/prime[j]);
g2[i]-=prime[j]*(g2[k]-sumPrime[j-]);
}
}
for(int i=;i<=m;++i)g2[i]-=g1[i];
}
ll S(ll n,ll j)
{
if(n<prime[j])return ;
int k=where(n);
ll sum=g2[k]-sumPrime[j-]+j-;
for(ll i=j;prime[i]*prime[i]<=n;++i)
for(ll e=,s=prime[i]*prime[i],ans=(prime[i]-);s<=n;s*=prime[i],ans*=prime[i],++e)
sum+=ans*S(n*prime[i]/s,i+)+ans*prime[i];
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
sqr=sqrt(n)+;
init(sqr);
calc1();
calc2();
cout<<S(n,)+<<endl;
return ;
}
5.求[1,n]中mu的和。
考虑到mu函数中若指数大于等于2,就为0了,所以在S函数中不需要枚举指数。
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll maxn=1E6+;
ll back[maxn],id1[maxn],id2[maxn],n,m,size,prime[maxn],sqr;
ll g[maxn];
bool vis[maxn];
void put(ll x,ll y)
{
if(x<=sqr)id1[x]=y;
else id2[n/x]=y;
}
ll where(ll x)
{
if(x<=sqr)return id1[x];
else return id2[n/x];
}
void init(ll s)
{
for(int i=;i<=s;++i)
{
if(!vis[i])prime[++size]=i;
for(int j=;j<=size&&prime[j]*i<=s;++j)
{
vis[prime[j]*i]=;
if(i%prime[j]==)break;
}
}
for(ll i=,j;i<=n;i=j+)
{
back[++m]=n/i;
j=n/back[m];
put(n/i,m);
g[m]=n/i-;
}
}
void calc()
{
for(int j=;j<=size;++j)
{
ll limit=prime[j]*prime[j];
for(int i=;back[i]>=limit;++i)
{
int k=where(back[i]/prime[j]);
g[i]-=g[k]-j+;
}
}
}
ll S(ll n,ll j)
{
if(n<prime[j])return ;
int k=where(n);
ll sum=g[k]-j+;
for(ll i=j;prime[i]*prime[i]<=n;++i)
sum+=-S(n/prime[i],i+);
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
sqr=sqrt(n)+;
init(sqr);
calc();
cout<<-S(n,)+<<endl;
return ;
}
ATTENTION:筛的质数个数一定要开大一点!不然可能会有一些特别的边界来卡掉。
6.积性函数f(pk)=(pk(pk-1)),求前缀和。
把质数拆成p2-p,算出质数前缀和和质数平方前缀和,然后合并一下。
#include<bits/stdc++.h>
#define mod 1000000007
#define G 166666668
#define Gi 500000004
using namespace std;
typedef long long int ll;
const ll maxn=1E6+;
ll n,m,id1[maxn],id2[maxn],sqr,back[maxn],g1[maxn],g2[maxn];
ll sumPrimeS[maxn],prime[maxn],Size,sumPrime[maxn];
bool vis[maxn];
ll qpow(ll x,ll y)
{
ll ans=,base=x;
while(y)
{
if(y&)ans=ans*base%mod;
base=base*base%mod;
y>>=;
}
return ans;
}
void put(ll x,ll y)
{
if(x<=sqr)id1[x]=y;
else id2[n/x]=y;
}
ll where(ll x)
{
if(x<=sqr)return id1[x];
else return id2[n/x];
}
void init(ll q)
{
for(ll i=;i<=q;++i)
{
if(!vis[i])
{
prime[++Size]=i;
sumPrime[Size]=(sumPrime[Size-]+i)%mod;
sumPrimeS[Size]=(sumPrimeS[Size-]+i*i%mod)%mod;
}
for(ll j=;j<=Size&&prime[j]*i<=q;++j)
{
vis[i*prime[j]]=;
if(i%prime[j]==)break;
}
}
for(ll i=,j;i<=n;i=j+)
{
back[++m]=n/i;
j=n/back[m];
put(n/i,m);
g1[m]=((back[m]+)%mod*back[m]%mod*Gi%mod-+mod)%mod;
g2[m]=(back[m]%mod*(back[m]+)%mod*(back[m]*%mod+)%mod*G%mod-+mod)%mod;
}
}
void calc1()
{
for(ll j=;j<=Size;++j)
{
ll limit=prime[j]*prime[j];
for(ll i=;back[i]>=limit;++i)
{
ll k=where(back[i]/prime[j]);
g1[i]=(g1[i]-((g1[k]-sumPrime[j-]+mod)%mod)*prime[j]%mod+mod)%mod;
}
}
}
void calc2()
{
for(ll j=;j<=Size;++j)
{
ll limit=prime[j]*prime[j];
for(ll i=;back[i]>=limit;++i)
{
ll k=where(back[i]/prime[j]);
g2[i]=(g2[i]-((g2[k]-sumPrimeS[j-]+mod)%mod)*prime[j]%mod*prime[j]%mod+mod)%mod;
}
}
}
ll S(ll n,ll j)
{
// cout<<n<<' '<<j<<endl;
if(n<prime[j])return ;
ll k=where(n);
ll sum=(g1[k]-sumPrimeS[j-]+sumPrime[j-]+mod)%mod;
for(ll i=j;prime[i]*prime[i]<=n;++i)
for(ll e=,s=prime[i],ans=prime[i];s<=n;++e,s*=prime[i],ans=ans*prime[i]%mod)
{
sum=(sum+S(n/s,i+)*ans%mod*(ans-)%mod)%mod;
if(e!=)sum=(sum+ans*(ans-)%mod)%mod;
}
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
sqr=sqrt(n)+;
init(sqr);
calc1();
calc2();
for(ll i=;i<=m;++i)
g1[i]=(g2[i]-g1[i]+mod)%mod;
cout<<S(n,)+<<endl;
return ;
}
https://www.luogu.org/problemnew/show/P5325
min_25筛题目总结的更多相关文章
- LG5325 【模板】Min_25筛
P5325 [模板]Min_25筛 题目背景 模板题,无背景. 题目描述 定义积性函数$f(x)$,且$f(p^k)=p^k(p^k-1)$($p$是一个质数),求 $$\sum_{i=1}^n f( ...
- 【UOJ448】【集训队作业2018】人类的本质 min_25筛
题目大意 给你 \(n,m\),求 \[ \sum_{i=1}^n\sum_{x_1,x_2,\ldots,x_m=1}^i\operatorname{lcm}(\gcd(i,x_1),\gcd(i, ...
- 【SPOJ】DIVCNTK min_25筛
题目大意 给你 \(n,k\),求 \[ S_k(n)=\sum_{i=1}^n\sigma_0(i^k) \] 对 \(2^{64}\) 取模. 题解 一个min_25筛模板题. 令 \(f(n)= ...
- 【51NOD1847】奇怪的数学题 min_25筛
题目描述 记\(sgcd(i,j)\)为\(i,j\)的次大公约数. 给你\(n\),求 \[ \sum_{i=1}^n\sum_{j=1}^n{sgcd(i,j)}^k \] 对\(2^{32}\) ...
- 【51NOD1965】奇怪的式子 min_25筛
题目描述 给你\(n\),求 \[ \prod_{i=1}^n{\sigma_0(i)}^{i+\mu(i)} \] 对\({10}^{12}+39\)取模. \(\sigma_0(i)\)表示约数个 ...
- LOJ6053 简单的函数 【Min_25筛】【埃拉托斯特尼筛】
先定义几个符号: []:若方括号内为一个值,则向下取整,否则为布尔判断 集合P:素数集合. 题目分析: 题目是一个积性函数.做法之一是洲阁筛,也可以采用Min_25筛. 对于一个可以进行Min_25筛 ...
- [复习]莫比乌斯反演,杜教筛,min_25筛
[复习]莫比乌斯反演,杜教筛,min_25筛 莫比乌斯反演 做题的时候的常用形式: \[\begin{aligned}g(n)&=\sum_{n|d}f(d)\\f(n)&=\sum_ ...
- LOJ.6235.区间素数个数(Min_25筛)
题目链接 \(Description\) 给定\(n\),求\(1\sim n\)中的素数个数. \(2\leq n\leq10^{11}\). \(Solution\) Min_25筛.只需要求出\ ...
- LOJ.6053.简单的函数(Min_25筛)
题目链接 Min_25筛见这里: https://www.cnblogs.com/cjyyb/p/9185093.html https://www.cnblogs.com/zhoushuyu/p/91 ...
随机推荐
- 高级shell 脚本
1.函数 函数是一个脚本代码块,你可以为其命名并在代码中任何位置重用.要在脚本中使用该代码块时,只要使用所起的函数名就行了(这个过程称为调用函数).本节将会介绍如何在shell脚本中创建和使用函数 创 ...
- Java线程基础(一)
说在前面,经过一段学习过后,自己发觉线程在Java中占有举足轻重的地位,总觉得如此复杂的线程知识点一定要好好理清才好消化,因而有了这篇文章. 但因鄙人资历尚浅,如有遗漏错误之处还请广大网友不吝赐教. ...
- kali-通过获取路由器pin码套取无线网络密码shell脚本
直接上脚本吧, 我做个笔记. #************************************************************************* # > Fil ...
- IDEA汉化教程
https://blog.csdn.net/weixin_38500325/article/details/81393251
- 【POJ 2176】Folding
[原题链接]传送门 [题面大意] 一个字符串,可以将它改写成循环节带括号的形式进行压缩,输出压缩长度最小的字符串. [题解思路] 1.没思路没思路,不知道怎么乱搞,大概就可以想到动态规划. 2.套路区 ...
- javascript 之 数组
定义:var colors=new Array(); var colors=new Array(3); var colors=new Array('red'); var colors=['red',' ...
- webpack创建页面的过程
1.项目文件夹中创建各类型文件放置的文件夹,如:iTestingWeb文件夹下创建src dist文件夹,用途:src为源码 dist为生成后的文件放置位置,然后在源码文件夹中进一步按文件类型增加文件 ...
- 算法 set / multiset -- lower_bound()的二分搜索
lower_bound() 在数组中搜索时 搜不到 返回 .end(), 若需要返回0,用upper_bound()-lower_bound() 若要返回下一个下标 则需要在set / multis ...
- YY的GCD
YY的GCD 给出T个询问,询问\(\sum_{i=1}^N\sum_{j=1}^M(gcd(i,j)\in prime)\),T = 10000,N, M <= 10000000. 解 显然质 ...
- extract method
函数 简短,命名良好 函数名描述的是做什么 而不是怎么做 行数过高的代码中 将一大段做一个事的代码提取到独立的method 中 高层函数直接引用. 创建新函数 将提炼的代码平移到目标函数中 检查是否引 ...