定义数字 x x x是好数,有 ⌊ k x ⌋ \lfloor ^k\sqrt{x} \rfloor ⌊kx ⌋是 x x x的因子
求 [ 1 , n ] [1,n] [1,n]中有多少个好数字
当 k = 1 k=1 k=1时答案显然是 n n n
否则
考虑 ⌊ k x ⌋ \lfloor ^k\sqrt{x} \rfloor ⌊kx ⌋的取值范围
最坏情况下 k = 2 k=2 k=2,而 1 0 9 < 1 0 5 \sqrt{10^9}<10^5 109 <105
随意我们完全可以枚举 ⌊ k x ⌋ \lfloor ^k\sqrt{x} \rfloor ⌊kx ⌋的值
我们知道 1 k = 1 1^k=1 1k=1,所以 1 1 1对应的 ⌊ k x ⌋ \lfloor ^k\sqrt{x} \rfloor ⌊kx ⌋就是 1 1 1
我们也可以计算出 2 k 2^k 2k,显然 2 k 2^k 2k对应的 ⌊ k x ⌋ \lfloor ^k\sqrt{x} \rfloor ⌊kx ⌋就是 2 2 2
所以我们得到区间 [ 1 , 2 k − 1 ] [1,2^k-1] [1,2k−1]对应的 ⌊ k x ⌋ \lfloor ^k\sqrt{x} \rfloor ⌊kx ⌋是 1 1 1
区间 [ 2 k , 3 k − 1 ] [2^k,3^k-1] [2k,3k−1]对应的 ⌊ k x ⌋ \lfloor ^k\sqrt{x} \rfloor ⌊kx ⌋是 2 2 2
以此类推,计算这个区间内的贡献即可
注意计算 i k i^k ik时候手算,不然会爆 l o n g l o n g long\ long long long
#include <bits/stdc++.h>
using namespace std;
#define int long long
int t,n,k,casenum;
int get(int l,int r,int k)
{
return r/k - (l-1)/k;
}
signed main()
{
cin >> t;
while( t-- )
{
cin >> n >> k;
cout << "Case #" << ++casenum << ": ";
if( k==1 ) cout << n << endl;
else
{
int ans = 0, las = 1;
for(int i=2;i<=n;i++)
{
int now = 1;
//手动计算i^k放置爆long long
for(int j=1;j<=k&&now<=n;j++) now *= i;
ans += get(las,min(n,now-1),i-1);
las = now;
if( las>n ) break;
}
cout << ans << endl;
}
}
}