题目
题目链接:https://codeforces.com/contest/1499/problem/D
给定 (c,d,x),求有多少二元组 ((a,b)) 满足
[c imes ext{lcm}(a,b)-d imes gcd(a,b)=x
]
(Qleq 10^4;1leq c,d,xleq 10^7)。
思路
因为 ( ext{lcm}(a,b)) 一定是 (gcd(a,b)) 的倍数,所以等号左边一定是 (gcd(a,b)) 的倍数,那么 (gcd(a,b)) 必然是 (x) 的因子。
那么枚举 (x) 的所有因子 (i),就可以得到对应的 (gcd(a,b)=i, ext{lcm}(a,b)=frac{x+di}{c})。
设 (a=gcd(a,b) imes p_1^{a_1} imes p_2^{a_2} imes cdots,b=gcd(a,b) imes q_1^{b_1} imes q_2^{b_2} imes cdots),那么 ( ext{lcm}(a,b)=gcd(a,b) imes p_1^{a_1} imes p_2^{a_2} imes cdots imes q_1^{b_1} imes q_2^{b_2}cdots)。
也就是对于 (k=frac{ ext{lcm}(a,b)}{gcd(a,b)}) 的每一个质因子,我们分配到 (a) 中或者 (b) 中都是一种合法方案。记 (x) 的止因子数量为 (f(x)),那么方案数就是 (2^{f(k)})。
那么直接预处理出 (1sim 2 imes 10^7) 所有数的最大质因子,然后就可以预处理出 (f(x)) 了。
时间复杂度 (O(nlog log n+Qsqrt{x})),其中 (n=max(c,d)leq 10^7)。
代码
VP 的时候数组一开始只开到了 (10^7) 调了半天。。。
#include <bits/stdc++.h>
#define mp make_pair
#define ST first
#define ND second
using namespace std;
typedef long long ll;
typedef long double ld;
const int N=20000010;
int Q,m,c,d,x,prm[N],f[N],v[N];
ll ans;
bool vis[N];
void findprm(int n)
{
for (int i=2;i<=n;i++)
{
if (!vis[i]) prm[++m]=i;
for (int j=1;j<=m;j++)
{
if (n/prm[j]<i) break;
vis[i*prm[j]]=1;
}
}
for (int i=1;i<=m;i++)
for (int j=prm[i];j<=n;j+=prm[i])
v[j]=prm[i];
}
void calc(ll g)
{
ll l=x+g*d;
if (l%(1LL*c)) return;
l=l/(1LL*c);
if (l%g) return;
ans=ans+(1LL<<f[l/g]);
}
signed main()
{
findprm(N-1);
for (int i=2;i<N;i++)
{
int p=i;
while (!(p%v[i])) p/=v[i];
f[i]=f[p]+1;
}
scanf("%d",&Q);
while (Q--)
{
scanf("%d%d%d",&c,&d,&x);
ans=0;
for (int i=1;i*i<=x;i++)
if (!(x%i))
{
calc(i);
if (i*i!=x) calc(x/i);
}
cout<<ans<<endl;
}
return 0;
}