【CF1499D】The Number of Pairs 题目 思路 代码

题目链接: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;
}