标签:知识 end 如何 || lag 素数 register space flag
看上去并没有快多少 实际也是, 但在处理一些大数据时,差距就凸显出来了
#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define in inline
#define get getchar()
int read()
{
int t=0; char ch=get;
while(ch<'0' || ch>'9') ch=get;
while(ch<='9' && ch>='0') t=t*10+ch-'0',ch=get;
return t;
}
const int _=1e7+6;
int prime[_], tot, n; //tot是素数个数,prime是从小到大存放的素数数组
bool flag[_];//用来判断当前数已为素数,flag==1不是素数
int main()
{
n=read();
for (re int i=2;i<=n;i++)
{
if (!flag[i]) prime[++tot]=i; // 当前数没有被打上非素数标记
for (re int j=1;j<=tot&&prime[j]*i<=n;j++)
{ //保证prime[j]在已确定的素数范围内
flag[prime[j]*i]=1; //打上非素数标记
if(i%prime[j]==0) break; //若当前prime[j]已是i的约数
//剩下的不用重复处理,所以直接break
}
}
cout<<"TOT: "<<tot<<endl;
for (re int i=1;i<=tot;i++)
cout<<prime[i]<<' ';
return 0;
}
记录数字 i 的最小约数出现次数 minn[i]
然后通过我们以前的知识 小学奥数 知道d(i)==(每个质因数的指数+1)的积
然后利用线性筛的性质递推 minn[i] 与 d[i] 就好
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define get getchar()
#define in inline
#define re register
const int _=10000001;
int minn[_],n,tot,prime[_],d[_];
bool np[_];
int main()
{
cin>>n;
d[1]=1;
for(re int i=2; i<=n; i++)
{
if(np[i]==0) prime[++tot]=i,d[i]=2,minn[i]=1;
for(re int j=1;prime[j]*i<=n&&j<=tot;j++)
{
np[i*prime[j]]=1;
if(i%prime[j]==0)
{
minn[i*prime[j]]=minn[i]+1;
d[i*prime[j]]=d[i]/(minn[i]+1)*(minn[prime[j]*i]+1);
break;
}
minn[i*prime[j]]=1;
d[i*prime[j]]=d[i]*2;
}
}
for( re int i=1;i<=n;i++)
cout<<d[i]<<' ';
}
标签:知识 end 如何 || lag 素数 register space flag
原文地址:https://www.cnblogs.com/yzhx/p/11521073.html