给定一个区间范围a,b,a,b内所以可以表示为x^y的数字可以组成的二叉排序树有多少种...
只知道n个节点能够成的二叉排序树种类是卡特兰数...可以DP求...(leetcode某题)
那么现在 任务就是求出所有的x^y的数字...肯定要筛法..
一直在考虑81是9^2也是3^4那么会重复算啊..我那么傻逼不会容斥。
然后网上看到别人引入了一个基的概念...
定义一个数是基,当且仅当这个数不是另一个数的幂次方。我们可以在近似O(nlogn)的时间内找出[1,100000]内的所有的基。
然后对于每一个幂次k,通过二分找出x^k <= bound的基的个数,累加即可求得。
参考链接: 点击打开链接#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 100000007
#define inf 0x3f3f3f3f
#define eps 1e-9
int ism[100007],p[100007],cnt;
ll dp[5050];
void db()
{
cnt=0;
memset(ism,0,sizeof(ism));
for(ll i=2; i<=100000; i++)
{
if(!ism[i])
{
p[cnt++]=i;
for(ll j=i*i; j<=100000; j=j*i)
ism[j]=1;
}
}
dp[0]=1;
for(int i=1; i<5000; i++)
{
for(int j=0; j<i; j++)
dp[i]=(dp[i]+dp[j]*dp[i-1-j])%mod;
}
}
int main()
{
int t;
db();
scanf("%d",&t);
for(int cas=1; cas<=t; cas++)
{
ll a,b;
scanf("%lld %lld",&a,&b);
ll ans=0,x,y;
for(int i=2; i<34; i++)
{
x=(int)floor(pow(a-1,1.0/i)+eps);
y=(int)floor(pow(b,1.0/i)+eps);
ans+=(upper_bound(p,p+cnt,y)-p)-(upper_bound(p,p+cnt,x)-p);
}
printf("Case %d: %d\n",cas,ans?dp[ans]:0);
}
return 0;
}