Number
【题目描述】
最近Answer正在研究“幂次数”,一个正整数?被称为“幂次数”当且仅当
存在
。
好奇的Answer想要知道在1~?中有多少数是幂次数。
【输入格式】
输入文件number.in 包含1 个正整数?
【输出格式】
输出文件number.out 包含一个非负整数表示1~N中幂次数的个数
【样例输入1】
10
【样例输出1】
4
【样例解释】
1~10 中的幂次数有1,4,8,9
【样例输入2】
36
【样例输出2】
9
【数据规模】
对于40%的数据,N ≤ 10^6
对于70%的数据,N ≤ 10^12
对于100%的数据,N ≤ 10^18
这题我只会一种暴力的做法,时间复杂度大约
先将
内的贡献暴力求出来,如果
,res++;
因为如果
,他的贡献显然为1,这一段可以直接算,在减去res即可
#include <cstdio>
#include <bitset>
#include <cmath>
using namespace std;
#define LL long long
bitset<10000007>vis;
LL n,k=1,ans=1,res;
LL find(LL s) {
LL h=1,t=1000001;
while (h<=t) {
LL mid=(h+t)>>1;
if (mid*mid*mid>s) t=mid-1;
else h=mid+1;
}
if (h*h*h>s) h--;
return h;
}
int main() {
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
scanf("%lld",&n);
if (n<1) {
puts("0");
return 0;
}
k=find(n);
int z=sqrt(n);
for (LL i=2;i<=k;i++) {
if (vis[i]) continue;
vis[i]=1;
LL j;
for (j=i*i;j<=k;j*=i) vis[j]=1,ans++;
for (;;j*=i) {
if (j<=z) res++;
ans++;
if (j>n/i) break;
}
}
printf("%lld\n",ans+z-k-res);
}
好吧,还有yk等dalao秒出
做法,
我们先借用刚才的思想,找出不同根号段下的贡献,这些贡献显然是有重叠的
我们加上质因子个数为奇数的,减去为偶数的,(据说这就是莫比乌斯函数!)
#include <cstdio>
using namespace std;
#define LL long long
LL n,ans,b;
LL t[100];
LL find(int x) {
LL h=1,t=n,p;
while (h<t) {
LL mid=(h+t+1)>>1;
p=n;
for (int i=1;i<=x;i++) p/=mid;
if (p>=1) h=mid;
else t=mid-1;
}
return h;
}
int main() {
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
scanf("%lld",&n);
ans=1;
for (int i=2;i<=64;i++) {
b=1-t[i];
for (int j=i;j<=64;j+=i) t[j]+=b;
ans+=(find(i)-1)*b;
}
printf("%lld",ans);
}