概述
Educational Codeforces Round 106 (Rated for Div. 2)
Educational Codeforces Round 106 (Rated for Div. 2)
D. The Number of Pairs
题意:
给定 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
题解:
设 t = l c m ( a , b ) , g = g c d ( a , b ) t = lcm(a, b), g = gcd(a, b) t=lcm(a,b),g=gcd(a,b)
可以得到 c ∗ t − d ∗ g = x c * t - d * g = x c∗t−d∗g=x
因为 g ∣ t g | t g∣t
所有 方程有解时, g ∣ x g | x g∣x
所有将方程除上 g g g, 即: c ∗ t g − d = x g c * frac{t}{g} - d = frac{x}{g} c∗gt−d=gx
g ∣ x g | x g∣x, g g g为 x x x的因子
枚举 x x x所有因子可以求出 x g frac{x}{g} gx的值, 设 y = x g y = frac{x}{g} y=gx
将上述方程进行整理: t g = y + d c frac{t}{g} = frac{y + d}{c} gt=cy+d
右边的都是已知量。
左边:因为 a ∗ b = l c m ( a , b ) ∗ g c d ( a , b ) a * b = lcm(a, b) * gcd(a, b) a∗b=lcm(a,b)∗gcd(a,b) , 所有 t = l c m ( a , b ) = a ∗ b g c d ( a , b ) t = lcm(a, b) = frac{a * b}{gcd(a, b)} t=lcm(a,b)=gcd(a,b)a∗b
所以 t g = a ∗ b g c d ( a , b ) ∗ g c d ( a , b ) = a ∗ b g 2 = a g ∗ b g frac{t}{g} = frac{a * b} {gcd(a, b) * gcd(a, b)} = frac{a*b} {g ^2} = frac{a}{g} * frac{b}{g} gt=gcd(a,b)∗gcd(a,b)a∗b=g2a∗b=ga∗gb
所以 a g ∗ b g = y + d c frac{a}{g} * frac{b}{g} = frac{y + d}{c} ga∗gb=cy+d
因为 g = g c d ( a , b ) g = gcd(a, b) g=gcd(a,b)
所以 g c d ( a g , b g ) = 1 gcd(frac{a}{g}, frac{b}{g}) = 1 gcd(ga,gb)=1
也就是说 y + d c frac{y + d}{c} cy+d 中有多少对因子 f , z f, z f,z, 使得 f ∗ z = y + d c f * z = frac{y +d}{c} f∗z=cy+d且 g c d ( f , z ) = 1 gcd(f, z) = 1 gcd(f,z)=1
可以将 y + d c frac{y + d}{c} cy+d的所有质因子求出来, 那么上述条件的方案数就是, 对于每种质因子, 要么全部都要
要么都不要, 也就是说 ( f , z ) (f, z) (f,z)有 2 n 2 ^ n 2n种方案( n n n是 y + d c frac{y +d}{c} cy+d的质因数种类)。那么等价于 ( a , b ) (a, b) (a,b)有 2 n 2 ^ n 2n中方案。
所以时间复杂度为 q ∗ s q r t ( n ) q * sqrt(n) q∗sqrt(n)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e7 + 7;
int vis[N], cnt[N];
ll c, d, x;
ll work(ll g) {
if ((x / g + d) % c) return 0;
return 1ll* 1 << 1ll*cnt[(x / g + d) / c];
}
int main() {
for (int i = 2; i < N; i++) {
if (vis[i]) continue;
for (int j = i; j < N; j += i) {
cnt[j]++;
vis[j] = 1;
}
}
int t; scanf("%d", &t);
while (t--) {
scanf("%lld %lld %lld", &c, &d, &x);
ll ans = 0;
for (ll i = 1; i * i <= x; i++) {
if (x % i == 0) {
ans += work(i);
if (x / i != i) ans += work(x / i);
}
}
printf("%lldn", ans);
}
}
最后
以上就是壮观绿草为你收集整理的Educational Codeforces Round 106 (Rated for Div. 2)Educational Codeforces Round 106 (Rated for Div. 2)的全部内容,希望文章能够帮你解决Educational Codeforces Round 106 (Rated for Div. 2)Educational Codeforces Round 106 (Rated for Div. 2)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复