フォームM ^ Kの数n内の包含および除外の数を求める - HDU-2204-渦の趣味
【問題の内容】
わずかに
【解決】
インデックスの\(k個\) 、最大の一つ見つける\(m個\)をするように\(M ^ K \ル\ N-) 、その後、\(k個\)の答えのインデックスへの寄与はさ\(m個\)、なぜなら以下のための\(iは[1、で\ \ M]) 数の\(I ^ k個の\)定数以下\(N- \) 。そして\(^ {N-M = \ FRAC。1 {{}}} K \)。分解定理からのみ明らかで、\(K \)定数は、素数の数の積として表すことができます。私たちは、検討する必要があります(64 \)\することができ素数以内。値が重複しますが、例えば、\(^ 2 = 8 4 3 ^ 2 = ^ {2 \}を3回\) 、再撥容量を使用することができることが必要です。
【コード】
#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;
}