质数
质数的筛选
埃氏筛法
扫描到每个x时,将x的倍数标记成合数。扫描到一个数而该数未被标记的时候,该数就是质数。可以发现,小于 x 2 x^2 x2的x的倍数之前已经被比x小的数标记过了,所以只需要从 x 2 x^2 x2开始标记就行了。时间复杂度: O ( N l o g l o g N ) O(NloglogN) O(NloglogN)
void prime(int n)
{
memset(v,0,sizeof(v));//合数标记
for(int i=2;i<=n;i++)
{
if(v[i])continue;
//cout<<i<<endl;
for(int j=i;j<=n/i;j++)
v[i*j]=1;
}
}
欧拉筛法
设数组v记录每个数的最小质因数,按照以下步骤维护v:
- 依次考虑2~N之间的每一个数i;
- 若v[i]=i,说明i是质数,把它保存下来;
- 扫描不大于v[i]的每一个质数p,令v[ip]=p。也就是在i的基础上累积一个质因子,因为p<=v[i],所以p就是合数ip的最小质因子。
每个合数i*p只会被它的最小质因子p筛一次。总时间复杂度 O ( n ) O(n) O(n)
int v[N],prime[N];
void primes(int n)
{
memset(v,0,sizeof(v));//最小质因子
m=0;//质数数量
for(int i=2;i<=n;i++)
{
if(v[i]==0)
v[i]=i,prime[++m]=i;//i是质数
//给当前的数i乘上一个质因子
for(int j=1;j<=m;j++)
{
if(prime[j]>v[i]||prime[j]>n/i) break;
//i有比prime[j]更小的质因子,或者超出n的范围,停止循环
v[i*prime[j]]=prime[j];
//prime[j]是合数i*prime[j]的最小质因子
}
}
}
质因数分解
#include<bits/stdc++.h>
#define llg long long
#define inf 1e9
using namespace std;
const int N=1e6+10;
llg v[N],prime[N];
int vis[N];
int main()
{
llg l,r;
while(~scanf("%lld%lld",&l,&r))
{
memset(prime,0,sizeof(prime));
memset(vis,0,sizeof(vis));
memset(v,0,sizeof(v));
int n=sqrt(r);
for(int i=2;i<=n;i++)
{
if(!v[i]) prime[++prime[0]]=i;
if(v[i]) continue;
for(int j=i;j<=n/i;j++)
v[i*j]=1;
}
for(int i=1;i<=prime[0];i++)
{
//cout<<prime[i]<<' ';
for(int j=l/prime[i];j*prime[i]<=r;j++)
{
if(prime[i]*j>=l&&j!=1)
vis[prime[i]*j-l]=1;
}
}
if(l==1) vis[0]=1;
llg pre=0,minn=inf,a,b,maxn=0,c,d;
for(llg i=l;i<=r;i++)
{
if(!vis[i-l])
{
//cout<<i-l<<' ';
if(pre)
{
if(i-pre<minn)
{
minn=i-pre;
a=pre;
b=i;
}
if(i-pre>maxn)
{
maxn=i-pre;
c=pre;
d=i;
}
}
pre=i;
}
}
if(minn==inf||maxn==0) cout<<"There are no adjacent primes."<<endl;
else printf("%lld,%lld are closest, %lld,%lld are most distant.\n",a,b,c,d);
}
return 0;
}
#include<bits/stdc++.h>
#define llg long long
#define inf 0x3ffffff
using namespace std;
const int N=1e6+10;
int v[N],p[N];
llg c[N];
int main()
{
int n;
cin>>n;
for(int i=2;i<=n;i++)
{
if(!v[i]) p[++p[0]]=i;
if(v[i]) continue;
for(int j=i;j<=n/i;j++)
v[i*j]=1;
}
for(int i=1;i<=p[0];i++)
{
for(llg j=p[i];j<=n;j*=p[i])
c[p[i]]+=(n/j);
cout<<p[i]<<' '<<c[p[i]]<<endl;
}
return 0;
}
约数
#include<bits/stdc++.h>
#define inf 0x3ffffff
using namespace std;
int a[]={2,3,5,7,11,13,17,19,23,29};
int n,ans=inf,maxn;
void dfs(int temp,int last,int now,int cnt)
//temp当前乘积,last上一个质因数的指数,now第几个质数,cnt约数个数
{
if(cnt>maxn||(cnt==maxn&&temp<ans))
{
maxn=cnt;
ans=temp;
}
for(int i=1;i<=last;i++)
{
if((long long)temp*a[now]>n) break;
temp*=a[now];
dfs(temp,i,now+1,cnt*(i+1));
}
}
int main()
{
cin>>n;
dfs(1,30,0,1);
cout<<ans;
return 0;
}
#include<bits/stdc++.h>
#define llg long long
#define inf 0x3ffffff
using namespace std;
llg n,k,ans;
int main()
{
cin>>n>>k;
ans=n*k;
int l,r;
for(l=1;l<=n;l=r+1)
{
if(k/l== 0) break;
r=min(k/(k/l),n);
ans-=(k/l)*(l+r)*(r-l+1)/2;
}
cout<<ans;
return 0;
}