概述
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
−
d
⋅
g
c
d
=
x
c cdot lcm - d cdot gcd = x
c⋅lcm−d⋅gcd=x
限制
1 ≤ T ≤ 1 0 4 1le Tle 10^4 1≤T≤104
1 ≤ c , d , x ≤ 1 0 7 1le c,d,xle 10^7 1≤c,d,x≤107
思路
对于原式
c
⋅
l
c
m
−
d
⋅
g
c
d
=
x
c cdot lcm - d cdot gcd = x
c⋅lcm−d⋅gcd=x
由
g
c
d
gcd
gcd及
l
c
m
lcm
lcm的数学性质,很容易得到一个结论:
l
c
m
lcm
lcm定是
g
c
d
gcd
gcd的倍数。
那么便能将上式化为
l
c
m
=
x
+
d
⋅
g
c
d
c
lcm=frac{x+dcdot gcd}{c}
lcm=cx+d⋅gcd
右侧定是一个整数,即
x
+
d
⋅
g
c
d
x+dcdot gcd
x+d⋅gcd定是
c
c
c的倍数
那么我们可以 O ( x ) O(sqrt x) O(x)枚举 x x x的所有因子作为 g c d gcd gcd
由于 c , d , x c,d,x c,d,x已知,在满足上述条件的前提下,可通过 g c d , c , d , x gcd,c,d,x gcd,c,d,x直接计算出所匹配的 l c m lcm lcm
问题现在便转化成了 “在已知 g c d gcd gcd与 l c m lcm lcm的前提下求有多少对整数对满足条件”
从数学角度可知
g c d ( a , b ) gcd(a,b) gcd(a,b)是 a , b a,b a,b的质因子的交集
l c m ( a , b ) lcm(a,b) lcm(a,b)是 a , b a,b a,b的质因子的并集
那么 l c m g c d frac{lcm}{gcd} gcdlcm便是多出来的质因子的乘积
对于 l c m g c d frac{lcm}{gcd} gcdlcm的每种质因子,不论数量,都应该全数位于 a g c d frac{a}{gcd} gcda或者全数位于 b g c d frac{b}{gcd} gcdb中
否则,这些质因子在 a a a与 b b b中同时出现,便会算在 g c d gcd gcd中,于此时情况不符
所以如果我们想要构造 a , b a,b a,b两个数,每种质因子只能够挑其中一个数乘进去
设 l c m g c d frac{lcm}{gcd} gcdlcm的质因子种类数为 n n n,则能够构造出的整数对共有 2 n 2^n 2n种
实践可得, 在线的质因子分解算法都将会完美地TLE 15
所以考虑离线处理每个数拥有的质因子种类数
这里的写法类似于埃氏素数筛法,详情见代码部分的 i n i t init init函数
注意 x g c d + d c frac{frac{x}{gcd}+d}{c} cgcdx+d的数据范围理论上最大可能达到 2 ⋅ 1 0 7 2cdot 10^7 2⋅107
代码
(1075ms/2000ms)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=2e7;
int r[MAXN+50]; //记录每个数字的质因子种类数
void init()
{
for(int i=2;i<=MAXN;i++)
if(!r[i]) //判断i是否为素数
{
for(int j=i;j<=MAXN;j+=i)
r[j]++; //i在范围内的倍数的质因子种类数++
}
}
ll c,d,x,ans;
void add(int gcd)
{
ll lcm=x+d*gcd;
if(lcm%c==0)
{
lcm/=c;
if(lcm%gcd==0)
ans+=1LL<<r[lcm/gcd];
}
}
void solve()
{
ans=0;
cin>>c>>d>>x;
int s=sqrt(x);
for(int i=1;i<=s;i++)
{
if(x%i==0) //枚举x的因子i
{
add(i);
if(i*i!=x)
add(x/i);
}
}
cout<<ans<<'n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
init();
int T;cin>>T;while(T--)
solve();
return 0;
}
https://www.cnblogs.com/stelayuri/p/14556665.html
最后
以上就是大胆外套为你收集整理的Codeforces 1499D - The Number of Pairs (数学)题意思路代码的全部内容,希望文章能够帮你解决Codeforces 1499D - The Number of Pairs (数学)题意思路代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复