LINK

定义数字 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,2k1]对应的 ⌊ k x ⌋ \lfloor ^k\sqrt{x} \rfloor kx 1 1 1

区间 [ 2 k , 3 k − 1 ] [2^k,3^k-1] [2k,3k1]对应的 ⌊ 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;
		}
	}
}