题目大意

给出数a0, a1, b0, b1,求满足gcd(a0, x)=a1, lcm(b0, x)=b1的x的个数

解法一

枚举b1的因数,看看是否满足上述条件。

怎样枚举因数

试除法。对于1~sqrt(b1)的所有数i,若其能被b1整除,则i和b1/i便是b1的质因数。

注意

  • 是sqrt(b1),而不是sqrt(b1)+1。不要擅自主张,因为这样sqrt(b1)~sqrt(b1+1)中的能被b1整除的数就被算重了。
  • 求lcm时,应当为a/gcd(a,b)*b,而不是a*b/gcd(a,b)。因为a*b可能会爆int。
#include <cstdio>
#include <cstring>
#include <cstdarg>
#include <cmath>
#include <cassert>
using namespace std; const int MAX_P = 45000, MAX_P_CNT = 30000;
int Primes[MAX_P_CNT];
int A, B, Gcd, Lcm, AnsCnt, N; void GetPrime(int *prime, int n)
{
static bool NotPrime[MAX_P];
memset(NotPrime, false, sizeof(NotPrime));
int primeCnt = 0;
for (int i = 2; i <= n; i++)
{
if (!NotPrime[i])
prime[primeCnt++] = i;
for (int j = 0; j < primeCnt; j++)
{
if (prime[j] * i > n)
break;
NotPrime[prime[j] * i] = true;
if (i%prime[j] == 0)
break;
}
}
} int GetGcd(int a, int b)
{
return b ? GetGcd(b, a%b) : a;
} int GetLcm(int a, int b)
{
return a / GetGcd(a, b) * b;//易忘点:Not a * b / GetGcd(a, b)
} void Dfs(int pos, int prod, int curTime)
{
if (pos>=0 && Primes[pos] > N)
return;
assert(Lcm%prod == 0);
if (curTime > 0)
{
if (GetGcd(prod, A) == Gcd && GetLcm(prod, B) == Lcm)
AnsCnt++;
int d = Lcm / prod;
if (d != prod && GetGcd(d, A) == Gcd && GetLcm(d, B) == Lcm)
AnsCnt++;
}
for (int time = 0; prod <= N && Lcm%prod==0; time++)
{
Dfs(pos + 1, prod, time);
prod *= Primes[pos + 1];
}
} int main()
{
GetPrime(Primes, MAX_P);
int caseCnt;
scanf("%d", &caseCnt);
while (caseCnt--)
{
scanf("%d%d%d%d", &A, &Gcd, &B, &Lcm);
AnsCnt = 0;
N = sqrt(Lcm);//易忘点:Don't plus 1
Dfs(-1, 1, 1);
printf("%d\n", AnsCnt);
}
return 0;
}

解法二

每个数都可以用Πp[i]^m[i](p[i]是质数)表示,对于两个数a,b的最大公因数,它每一个p[i]的m[i]是a,b的m[i]中的较小值,最小公倍数是较大值。最终的结果便是每个p[i]计算出的满足较大较小关系的x的取值范围的大小。

注意

枚举n的质因数时,可能存在一个质数p>sqrt(n)。此时不要忘了它呀!

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdarg>
using namespace std; const int MAX_P = 45000, MAX_P_CNT = 3000;
int Primes[MAX_P_CNT];
int TotPrime; int GetPrime(int *prime, int n)
{
static bool NotPrime[MAX_P];
memset(NotPrime, false, sizeof(NotPrime));
int primeCnt = 0;
for(int i=2; i<=n; i++)
{
if (!NotPrime[i])
prime[primeCnt++] = i;
for (int j = 0; j < primeCnt; j++)
{
if (i*prime[j] > n)
break;
NotPrime[i*prime[j]] = true;
if (i%prime[j] == 0)
break;
}
}
return primeCnt;
} int GetM(int prime, int &x)
{
int cnt = 0;
while (x%prime == 0)
{
cnt++;
x /= prime;
}
return cnt;
} void DoPrime(int prime, int &ans, int &a, int &gcd, int &b, int &lcm)
{
int mA = GetM(prime, a), mGcd = GetM(prime, gcd), mB = GetM(prime, b), mLcm = GetM(prime, lcm);
if (mA == mGcd && mB == mLcm && mGcd <= mLcm)
ans *= mLcm - mGcd + 1;//x *= prime ^ (mGcd ~ mLcm)
else if (mA == mGcd && mB < mLcm && mGcd <= mLcm)
ans *= 1;//x *= prime ^ (mLcm)
else if (mA > mGcd && mB == mLcm && mGcd <= mLcm)
ans *= 1;//x *= prime ^ (mGcd)
else if (mA > mGcd && mB < mLcm && mGcd == mLcm)
ans *= 1;//x *= (mGcd == mLcm)
else
ans *= 0;
} int Proceed(int a, int gcd, int b, int lcm)
{
int ans = 1, end = max(a, lcm);
for (int p = 0; Primes[p] <= end && ans && p<TotPrime; p++)
DoPrime(Primes[p], ans, a, gcd, b, lcm);
if (a > 1)
DoPrime(a, ans, a, gcd, b, lcm);
else if (lcm > 1 && lcm != a)
DoPrime(lcm, ans, a, gcd, b, lcm);
return ans;
} int main()
{
TotPrime = GetPrime(Primes, MAX_P);
int caseCnt;
scanf("%d", &caseCnt);
while (caseCnt--)
{
int a, gcd, b, lcm;
scanf("%d%d%d%d", &a, &gcd, &b, &lcm);
printf("%d\n", Proceed(a, gcd, b, lcm));
}
return 0;
}

  

luogu1072 Hankson的趣味题的更多相关文章

  1. 算法训练 Hankson的趣味题

    算法训练 Hankson的趣味题   时间限制:1.0s   内存限制:64.0MB        问题描述 Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫Han ...

  2. 1172 Hankson 的趣味题[数论]

    1172 Hankson 的趣味题 2009年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Descrip ...

  3. 1172 Hankson 的趣味题

    1172 Hankson 的趣味题 2009年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Descrip ...

  4. Codevs 1172 Hankson 的趣味题 2009年NOIP全国联赛提高组

    1172 Hankson 的趣味题 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description Hanks 博 ...

  5. 一本通1626【例 2】Hankson 的趣味题

    1626:[例 2]Hankson 的趣味题 题目描述 Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫Hankson.现在,刚刚放学回家的Hankson 正在思考 ...

  6. 洛谷 P1072 Hankson 的趣味题 解题报告

    P1072 \(Hankson\)的趣味题 题目大意:已知有\(n\)组\(a0,a1,b0,b1\),求满足\((x,a0)=a1\),\([x,b0]=b1\)的\(x\)的个数. 数据范围:\( ...

  7. CH3201 Hankson的趣味题

    题意 3201 Hankson的趣味题 0x30「数学知识」例题 描述 Hanks博士是BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫Hankson.现在,刚刚放学回家的Hankson ...

  8. luogu P1072 Hankson的趣味题

    题目链接 luogu P1072 Hankson 的趣味题 题解 啊,还是noip的题好做 额,直接推式子就好了 \(gcd(x,a_0)=a_1=gcd(\frac{x}{a_1},\frac{a_ ...

  9. 洛谷P1072 Hankson 的趣味题

    P1072 Hankson 的趣味题 题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson.现在,刚刚放学回家的 Hankson 正在思考一 ...

随机推荐

  1. 另一种压缩图片的方法---Machine learning 之 PCA(Principle Component Analysis)

    PCA最主要的用途是用来减少特征向量的数目,N个特征向量 减小到 K个特征向量.如果为了可视化,k可以使3 或者 2.这样可以加速算法的学习速度. PCA用来压缩图像同一有效. 具体方式以及原理在gi ...

  2. SQLServer2008 将“单个用户”改为“多用户”

    一开始是要想要分离掉数据库,然后将其删除 不知道为什么一直分离不了,试了很多次,又尝试直接删除 结果数据库突然显示成了“单个用户” 尝试查看其属性,或者“新建查询”也都报错,提示已经有其他用户建立了连 ...

  3. CSS画各种二维图形

    1.效果 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %> ...

  4. 我和CSDN的那些事

    作者:朱金灿 来源:http://blog.csdn.net/clever101 前些日子收到这样一个邀请: CSDN的工作人员还来电给我确认是否能参加.开始我有点犹豫,毕竟是在工作日的晚上,毕竟离我 ...

  5. Android 解决小米手机Android Studio安装app 报错的问题It is possible that this issue is resolved by uninstalling an existi

    Android Studio升级到2.3版本之后,小米手机MIUI8不能运行Android Studio程序,报如下错误: Installation failed with message Faile ...

  6. html 表单赋值 和 时间戳 转换

    <script> window.onload = function () { var str; // console.log(@ViewBag.ID); $.post("/Ser ...

  7. java HttpURLConnection 登录网站 完整代码

    import java.io.*; import java.util.*; import java.net.*; public class WebTest { public static void m ...

  8. 移动端APP UI规范

  9. 然而,该来的还是来了(Diary)

    2017-05-07     LG月赛成功炸掉...发现自己真的好多东西不会啊.对某些知识仅仅有最基础的一点理解啊!连线段树都理解不了怎么办?归并排序(including分治+贪心)全部炸掉啊.感觉自 ...

  10. 数据结构实验病毒感染检测问题(C++)

    医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知他们的DNA序列都是环状的.现在研究者已收集了大量的病毒DNA和人的DNA数据,想快速检测出这些人是否感染了相应的病毒.为了方便研究,研究者将 ...