The Number of Pairs (Codeforces 1499D)
Tags: Math, number theory

You are given three positive (greater than zero) integers $$$c$$$, $$$d$$$ and $$$x$$$. You have to find the number of pairs of positive integers $$$(a, b)$$$ such that equality $$$c \cdot lcm(a, b) - d \cdot gcd(a, b) = x$$$ holds. Where $$$lcm(a, b)$$$ is the least common multiple of $$$a$$$ and $$$b$$$ and $$$gcd(a, b)$$$ is the greatest common divisor of $$$a$$$ and $$$b$$$.

Input: The first line contains one integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases.Each test case consists of one line containing three integer $$$c$$$, $$$d$$$ and $$$x$$$ ($$$1 \le c, d, x \le 10^7$$$).

Output: For each test case, print one integer — the number of pairs ($$$a, b$$$) such that the above equality holds.

Note: In the first example, the correct pairs are: ($$$1, 4$$$), ($$$4,1$$$), ($$$3, 6$$$), ($$$6, 3$$$).In the second example, the correct pairs are: ($$$1, 2$$$), ($$$2, 1$$$), ($$$3, 3$$$).

Sample Inputs:
4
1 1 3
4 2 6
3 3 7
2 7 25

Sample Outputs:
4
3
0
8

Solution (Python):
import sys
input = sys.stdin.buffer.readline

def print(val):
    sys.stdout.write(str(val) + '\n')
maxn = 2 * 10 ** 7
whyistimelimitsotight = {}
pairs = [0] * (maxn + 1)
spf = [0] * (maxn + 1)
primes = []
for i in range(2, maxn + 1):
    if spf[i] == 0:
        spf[i] = i
        primes.append(i)
    j = 0
    while j < len(primes) and primes[j] <= spf[i] and (primes[j] * i <= maxn):
        spf[primes[j] * i] = primes[j]
        j += 1
for i in range(2, maxn + 1):
    prev = i // spf[i]
    pairs[i] += pairs[prev] + (spf[prev] != spf[i])

def divisors(n):
    pf = []
    while n > 1:
        if len(pf) == 0 or pf[-1][0] != spf[n]:
            pf.append([spf[n], 1])
        else:
            pf[-1][1] += 1
        n //= spf[n]
    divs = [1]
    for (prime, count) in pf:
        l = len(divs)
        prime_pow = 1
        for i in range(count):
            prime_pow *= prime
            for j in range(l):
                divs.append(divs[j] * prime_pow)
    return divs
for _ in range(int(input())):
    (c, d, x) = map(int, input().split())
    ans = 0
    if x in whyistimelimitsotight:
        divs = whyistimelimitsotight[x]
    else:
        whyistimelimitsotight[x] = divs = divisors(x)
    for i in divs:
        e = x // i + d
        if e % c == 0:
            ans += 1 << pairs[e // c]
    print(ans)

Solution (Python):
import os
import sys
from io import BytesIO, IOBase

def seieve_prime_factorisation(n):
    (p, i) = ([0] * (n + 1), 2)
    while i <= n:
        if not p[i]:
            for j in range(i, n + 1, i):
                p[j] += 1
        i += 1
    return p

def main():
    p = seieve_prime_factorisation(20000000)
    po = [1]
    for i in range(10):
        po.append(po[-1] * 2)
    for _ in range(int(input())):
        (c, d, x) = map(int, input().split())
        (f, i) = ([], 1)
        while i * i <= x:
            if not x % i:
                if x // i != i:
                    f.append(x // i)
                f.append(i)
            i += 1
        ans = 0
        for i in f:
            if (x // i + d) % c == 0:
                ans += po[p[(x // i + d) // c]]
        print(ans)
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = 'x' in file.mode or 'r' not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b'\n') + (not b)
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            (self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode('ascii'))
        self.read = lambda : self.buffer.read().decode('ascii')
        self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
if __name__ == '__main__':
    main()

Solution (Python):
import sys
count = [0] * 20000010
for i in range(2, 20000001):
    if count[i] == 0:
        for j in range(i, 20000001, i):
            count[j] += 1
input = sys.stdin.readline
t = int(input())
for _ in range(t):
    (a, b, c) = map(int, input().split())
    ans = 0
    for g in range(1, int(c ** 0.5) + 1):
        if c % g == 0:
            d = c // g + b
            if d % a == 0:
                ans += 2 ** count[d // a]
            if g ** 2 != c:
                d = g + b
                if d % a == 0:
                    ans += 2 ** count[d // a]
    print(ans)