略php
對於一個指數\(k\),找到一個最大的\(m\)使得\(m^k\le n\),則\(k\)這個指數對答案的貢獻爲\(m\),由於對於\(i\in[1,m]\)中的數\(i^k\)必定小於等於\(n\)。而\(m=n^{\frac{1}{k}}\)。由惟一分解定理可知,\(k\)必定能表示爲一些素數的乘積。因此只須要考慮\(64\)之內的素數便可。可是會出現重複的值,例如\(8^2=4^3=2^{2\times 3}\),因此須要用容斥去重便可。ios
#include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; #define int long long #define INF 0x3f3f3f3f #define maxn 65 int prime[maxn],cnt=0; bool vis[maxn]={1,1}; void Euler(){ //歐拉篩素數 for(int i=2;i<maxn;i++){ if(!vis[i]) prime[++cnt]=i; for(int j=1;j<=cnt&&i*prime[j]<maxn;j++){ vis[i*prime[j]]=1; if(i%prime[j]==0) break; } } } int n,ans=0; int fpow(int a,int b){ //快速冪 int ans=1; while(b){ if(b&1) ans*=a; a*=a; b>>=1; } return ans; } void dfs(int pos,int num,int val){ //容斥 if(val>64) return ; //最大值不超過64 int tmp=pow(n,1.0/val)+0.1; //求最大的m if(fpow(tmp,val)>n) tmp--;tmp--; //精度判斷 if(num) if(num&1) ans+=tmp; else ans-=tmp; for(int i=pos+1;i<=cnt;i++){ dfs(i,num+1,val*prime[i]); } } signed main(){ ios::sync_with_stdio(false); cin.tie(0);Euler(); while(cin>>n){ ans=1;//1必定知足條件 dfs(0,0,1); cout<<ans<<endl; } return 0; }