D.Mr. Panda and Geometric Sequence
题意:给你一个l,r,问构造一个满足等比数列拼接而成的数在[l,r]区间内有多少个
其中等比数列的公比可以为分数
分析:对于每个数列的公比 设为p/q 且满足gcd(p,q)=1恒成立 因为数列最少要为3项 所以枚举第一项时 设x=ipp y=iqp z=iqq 这样保证前三个必为整数 且 y<=1e5 对于之后枚举的数要求
z*q%p == 0 最后存入答案 去重 二分查找
//https://codeforces.com/gym/101775/problem/D
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
int check(ll x){//拆分
if (x == 0) return 1;
int res = 0;
while (x){
res++;
x /= 10;
}
return res;
}
vector<ll>v;//存符合条件的数
ll f[17];
ll gcd(ll x, ll y){
return y == 0 ? x : gcd(y, x%y);
}
int cnt;//记录去重后的长度
void init(){//预处理
f[0] = 1;
for (int i = 1; i <= 16; i++)
f[i] = f[i - 1] * 10;
for (ll p = 1; p <= 1e5; p++){//枚举分母
for (ll q = p+1; q <= 1e5/p; q++)//枚举分子
{
if (gcd(p, q) != 1) continue;
for (ll i = 1; i <= 1e5 / p / q; i++){//枚举第一个数
ll x = i*p*p, y = i*p*q, z = i*q*q;
int xx = check(x), yy = check(y), zz = check(z);
if (xx + yy + zz > 15) break;
//接着枚举后面的位数
int len = xx + yy + zz;
ll sum = x*f[yy + zz] + y*f[zz] + z;
while (1){
v.push_back(sum);
if (z*q%p != 0) break;
ll a = z*q / p;
int aa = check(a);
if (len + aa > 15) break;
len += aa;
sum = sum*f[aa] + a;
z = a;
}
}
}
}
sort(v.begin(), v.end());
cnt=unique(v.begin(), v.end())-v.begin();
}
int main(){
init();
// for (auto it : v)
// cout << it << endl;
// cout << cnt << endl;//1117个
int T;
cin >> T;
int Cas = 0;
while (T--){
ll l, r;
scanf("%lld%lld", &l, &r);
int x = lower_bound(v.begin(), v.begin() + cnt, l) - v.begin();
int y = upper_bound(v.begin(), v.begin() + cnt, r) - v.begin()-1;
//cout << x << " " << y << endl;
printf("Case #%d: %d\n", ++Cas, y - x + 1);
}
return 0;
}