题意:
给定你
c
,
d
,
x
c,d,x
c,d,x三个数然问你存在多少对二元组
(
a
,
b
)
(a,b)
(a,b)使得等式
c
∗
l
c
m
(
a
,
b
)
−
d
∗
g
c
d
(
a
,
b
)
=
x
c * lcm(a,b) - d * gcd(a,b) = x
c∗lcm(a,b)−d∗gcd(a,b)=x恒成立,
(
a
,
b
)
(a,b)
(a,b)和
(
b
,
a
)
(b,a)
(b,a)算作两个不同的二元组。
纯抄袭大佬思路
思路一:
先把给定的式子转化一下,
c
∗
l
c
m
(
a
,
b
)
=
d
∗
g
c
d
(
a
,
b
)
+
x
c * lcm(a,b) = d * gcd(a,b) + x
c∗lcm(a,b)=d∗gcd(a,b)+x,两边同除
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b),得
l
c
m
(
a
,
b
)
g
c
d
(
a
,
b
)
=
x
g
c
d
(
a
,
b
)
+
d
c
\frac{lcm(a,b)}{gcd(a,b)} = \frac{\frac{x}{gcd(a,b)} + d}{c}
gcd(a,b)lcm(a,b)=cgcd(a,b)x+d,因为左边肯定是整数,所以这就决定了
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)必须是
x
x
x的因子。
l c m ( a , b ) g c d ( a , b ) \frac{lcm(a,b)}{gcd(a,b)} gcd(a,b)lcm(a,b)就是 a a a和 b b b中不相同的素因子这里不相等是指两边把相同幂次的素因子约去之后剩余的部分,可知这一部分的因子一定是一部分属于 a a a,一部分属于 b b b,二者是不相交的,所以本质就相当于我从 n n n种素因子中挑出两堆分给 a a a和 b b b,但是还有 1 1 1和这个数本身也是可以组合的,所以就是 ( n 0 ) \tbinom{n}{0} (0n) + ( n 1 ) \tbinom{n}{1} (1n) + . . . . .... .... + ( n n ) \tbinom{n}{n} (nn) = 2 n 2^n 2n,其中 n n n代表素因子个数。
特别地,挑0,那么另一边就是本身那个数,挑n,那么另一边就是0。
思路二:
另一种思路,
c
∗
a
∗
b
g
c
d
(
a
,
b
)
=
x
+
d
∗
g
c
d
(
a
,
b
)
c * \frac{a*b}{gcd(a,b)} = x + d * gcd(a,b)
c∗gcd(a,b)a∗b=x+d∗gcd(a,b),两侧同除
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)得
a
∗
b
g
c
d
(
a
,
b
)
∗
g
c
d
(
a
,
b
)
=
x
g
c
d
(
a
,
b
)
+
d
c
\frac{a*b}{gcd(a,b)*gcd(a,b)} = \frac{\frac{x}{gcd(a,b)} + d}{c}
gcd(a,b)∗gcd(a,b)a∗b=cgcd(a,b)x+d,设
A
=
a
g
c
d
(
a
,
b
,
B
=
b
g
c
d
(
a
,
b
)
A = \frac{a}{gcd(a,b},B = \frac{b}{gcd(a,b)}
A=gcd(a,ba,B=gcd(a,b)b,可知
A
A
A和
B
B
B互质,故其实就变为找到两个互质的数使它们相乘等于右侧,而右侧等式又可知
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)定为
x
x
x的因子,所以我们枚举
x
x
x的因子,然后找右侧这个数的素因子即可,再分配成两个部分相乘,同理也是
2
n
2^n
2n的数量。
其实 g c d ( a , b ) ∣ x gcd(a,b)|x gcd(a,b)∣x这个条件也可以有裴蜀定理的推论得到,若 a x + b y = z ax +by = z ax+by=z,对于整数 x x x和 y y y来说有解,那么 g c d ( a , b ) ∣ z gcd(a,b) | z gcd(a,b)∣z,而题目里的 g c d ( l c m ( a , b ) , g c d ( a , b ) ) = g c d ( a , b ) gcd(lcm(a,b),gcd(a,b)) = gcd(a,b) gcd(lcm(a,b),gcd(a,b))=gcd(a,b)。
需要注意的是,要预处理出每个数的素因子个数,每个数现算的话,会TLE,还有当对于数学式存在分式的同时,给出整数这个条件,可能就是突破口。
#include <bits/stdc++.h>
using namespace std;
#define pb emplace_back
#define MP make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>
#define lson rt<<1
#define rson rt<<1|1
#define CLOSE std::ios::sync_with_stdio(false)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-6;
const int N = 2e7;
bool is_prime[N + 10];
int Fac[N + 10],prime[N],cnt;
void Prime() {
for(int i = 2;i <= N;i ++) is_prime[i] = true;
for(int i = 2;i <= N;i ++) {
if(is_prime[i]) {
prime[++cnt] = i;
Fac[i] = 1;
}
for(int j = 1;j <= cnt && prime[j] * i <= N;j ++) {
is_prime[prime[j]*i] = false;
if(i % prime[j] == 0) {
Fac[prime[j]*i] = Fac[i];//这里其实i的素因子是包含prime[j]的,所以prime[j]是不能放进去的
break;
}
Fac[prime[j]*i] = Fac[i] + 1;
}
}
}
int d,c,x;
ll cal(int x) {
int tmp = d + x;
if(tmp % c == 0) {
tmp = tmp / c;
return 1LL << Fac[tmp];
}
return 0;
}
int main() {
Prime();
int T;scanf("%d",&T);
while(T--) {
scanf("%d%d%d",&c,&d,&x);
ll ans = 0;
for(int i = 1;i * i <= x;i ++) {
if(x % i == 0) {
ans += cal(x/i);
if(x / i != i)
ans += cal(i);
}
}
printf("%lld\n",ans);
}
return 0;
}