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<bits/stdc++.h>
#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<pair<int,int> >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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章