这道题因为加强了数据,所以以往大多数题解是过不了了,因为a,b$\le 10^{12}$,我们进行质因数分解,和枚举小于b的且是a的约数这两部分大多数题解都会超时,思路还是以往的思路,但是这里要采用更加优化的算法,而且当我们特判$b*b \ge a$时这儿会爆long long的所以我们需要用__int128来储存 b * b,那么我们这儿用了PR算法对大数进行质因数分解,时间复杂度是$n^{1/4}$大大的节约了时间,然后对于枚举小于b的a的约数采用dfs不重不漏的去搜,时间也大大的节省了。
C++ 代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr)
#define int long long
#define endl "\n"
using namespace std;
const int N = 1e6 + 10, mod = 998244353;
int n, m, k, _;
namespace prime_fac
{
const int S = 8;
int mult_mod(int a, int b, int c)
{
a %= c, b %= c;
int ret = 0;
int tmp = a;
while (b)
{
if (b & 1)
{
ret += tmp;
if (ret > c) ret -= c;
}
tmp <<= 1;
if (tmp > c) tmp -= c;
b >>= 1;
}
return ret;
}
int qow_mod(int a, int n, int _mod)
{
int ret = 1;
int temp = a % _mod;
while (n)
{
if (n & 1) ret = mult_mod(ret, temp, _mod);
temp = mult_mod(temp, temp, _mod);
n >>= 1;
}
return ret;
}
bool check(int a, int n, int x, int t)
{
int ret = qow_mod(a, x, n);
int last = ret;
for (int i = 1; i <= t; i++)
{
ret = mult_mod(ret, ret, n);
if (ret == 1 && last != 1 && last != n - 1) return true;
last = ret;
}
if (ret != 1) return true;
return false;
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
bool Miller_Rabin(int n)
{
if (n < 2) return false;
if (n == 2) return true;
if ((n & 1) == 0) return false;
int x = n - 1;
int t = 0;
while ((x & 1) == 0)
{
x >>= 1;
t++;
}
for (int i = 0; i < S; i++)
{
int a = rng() % (n - 1) + 1;
if (check(a, n, x, t))
return false;
}
return true;
}
int factor[100];
int tol;
int gcd(int a, int b)
{
int t;
while (b)
{
t = a;
a = b;
b = t % b;
}
if (a >= 0) return a;
return -a;
}
int pollard_rho(int x, int c)
{
int i = 1, k = 2;
int x0 = rng() % (x - 1) + 1;
int y = x0;
while (1)
{
i++;
x0 = (mult_mod(x0, x0, x) + c) % x;
int d = gcd(y - x0, x);
if (d != 1 && d != x) return d;
if (y == x0) return x;
if (i == k)
{
y = x0;
k += k;
}
}
}
void findfac(int n, int k)
{
if (n == 1) return;
if (Miller_Rabin(n))
{
factor[tol++] = n;
return;
}
int p = n;
int c = k;
while (p >= n) p = pollard_rho(p, c--);
findfac(p, k);
findfac(n / p, k);
}
vector<int> fac(int n)
{
tol = 0;
vector<int>ret;
findfac(n, 107);
for (int i = 0; i < tol; i++)ret.push_back(factor[i]);
return ret;
}
}
vector<pair<int,int> > v;
set<int> st;
void dfs(int x,int mul)
{
if(x == v.size())
{
st.insert(mul);
return;
}
int k = 1;
for(int i = 0; i <= v[x].second; ++i)
{
dfs(x+1,mul*k);
k *= v[x].first;
}
}
void solve(int op)
{
cout << "Case " << op << ": ";
int a, b;
cin >> a >> b;
__int128 ag = a, bg = b;
if(bg*bg >= ag)
{
cout << 0 << endl;
return;
}
v.clear();
vector<int> mp = prime_fac::fac(a);
int len = mp.size();
map<int, int> cp;
for(int i = 0; i < len; i ++)
{
cp[mp[i]]++;
}
int res = 1;
for(auto [x, y] : cp)
{
res *= (y+1);
v.push_back({x,y});
}
st.clear();
res /= 2;
dfs(0,1);
for(auto it : st) if(it < b) res--;
cout << res << endl;
}
signed main()
{
IOS;
cin >> _;
for(int i = 1; i <= _; i ++) solve(i);
return 0;
}