Project Euler 302 [Strong Achilles Numbers]

题目链接

Solution:

        欧拉函数公式φ(n)=n*n\varphi (n)=n*(\frac{p1-1}{p1})(\frac{p2-1}{p2}).....(\frac{pm-1}{pm})(pi表示n的每一个不同的质因子)。

        首先普通的Achilles Number有的性质是:

        (1)所有质因子次幂数>=2。(2)所有质因子次幂数的gcd=1。

        在此基础上考虑Strong Achilles Number的性质:

        最大质因子的次幂>=3.因为如果最大质因子次幂=2,那么根据欧拉函数公式,φ(p^2)=p*(p-1),而此时没有其它数可以贡献p的因子,即φ(n)只有一个p的因子,不符合Achilles Number的性质。除此之外,由这条推论我们还可以知道,只有p^3<=n的质数才可能作为答案的一个质因子。

        综上,考虑dfs枚举当前每一个质因子的次数,另外记一个phi表示φ(n)中所有(p-1)的乘积,每次先检查phi是否能使原所有n的质因子的次数不小于2,再判断乘上phi剩余部分是否满足Achilles Number的性质。

        (1e18跑了179s)

Code:

#include
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
long long n;int len=0;int l;
int prime[2000001];bool f[2000001];
inline void Pre(){
	rep(i,2,l){
		if(!f[i]){f[i]=i;prime[++len]=i;}
		rep(j,1,len){
			if(i*prime[j]>l)break;
			f[i*prime[j]]=1;
			if(i%prime[j]==0)break;
		}
	}
	return;
}

vector >v;long long ans=0;
inline int gcd(int n,int m){
	return ((!m)?n:gcd(m,n%m));
}
inline int chk(long long k){
	int s=0;long long x=k;
	rep(i,0,(int)v.size()-1){
		int ret=v[i].second;
		while(x%v[i].first==0){ret++;x/=v[i].first;}
		if(ret<2)return 0;
		s=gcd(s,ret);	
	}
	
	for(int j=1;prime[j]*prime[j]<=x;j++){
		int p=0;
		while(x%prime[j]==0){p++;x/=prime[j];}
		if(p==1)return 0;
		s=gcd(s,p);
	}
	return (s==1&&x==1);
}
inline void dfs(int dep,long long w,int ls,long long phi,int la,int z){
	if(ls==1&&la>=3&&z)ans+=chk(phi);
	if(dep>len)return;
	long long s=prime[dep];long long tmp=s*s;int p=2;
	if(w>n/tmp)return;
	while(w<=n/tmp){
		v.push_back(make_pair(s,p-1));
		dfs(dep+1,w*tmp,gcd(ls,p),phi*(s-1),p,1);	
		v.pop_back();
		if(s>n/tmp)break;
		tmp*=s;p++;
	}
	dfs(dep+1,w,ls,phi,la,0);return;
}

int main(){
	cin>>n;l=pow(n,0.34);
	Pre();
	
	dfs(1,1,0,1,0,0);
	printf("%lld\n",ans);
	return 0;
}

 

你可能感兴趣的:(欧拉函数,Project,Euler)