题目大意

给出数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. Kali linux 2016.2(Rolling)之 Nessus安装及Plugins Download Fail 解决方法

    最近,因科研需要,学习Nessus. Nessus是一款优秀的漏洞扫描软件,在其v6 HOME版本中在线更新漏洞插件不成功,采用离线更新,成功地更新了插件,在此将更新方法进行分享. 1.Nessus软 ...

  2. 【SQL】字符型函数

    1. ASCII ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统. 1) 返回 ...

  3. WEB笔记-CSS 实现多级导航效果

    代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  4. mvc自定义控件

    //自定义一个DatePicker.cshtml文件@helper Init() { <link href="~/Content/mobiscroll.custom-2.5.0.min ...

  5. MVC 返回404,返回图片,流到数组,apk信息

    return HttpNotFound(); byte[] buffer0 = QRCode(); return File(buffer0, @"image/jpeg"); // ...

  6. js-构造数组

    js中,字符串的特性跟数组非常类似.数组是一种很重要的数据结构.在java中,数组声明的时候就要为其指定类型,数组中只能放同一种类型的数据.Js中的数组可以放不同的类型,但是是有序的,类似于java中 ...

  7. 卸载hyper-v后 仍然提示 vmware 与 hyper-v 不兼容

    已经卸载了hyper-v 仍然提示 vmware 与 hyper-v 不兼容:天天模拟器,提示VT模式没有开启,BIOS里面已经设置过了 环境win10,vm的失败和模拟器的失败都是hyper-v冲突 ...

  8. 01-Linux命令基础-第01天(命令基础,软件安装与卸载、磁盘管理)

    01-   Linux初步 最早一直是单道程序设计模型的操作系统 69年贝尔实验室决定开发多道程序设计模型的操作系统 Multics计划 (失败了) x86 IA(Intel Architecture ...

  9. [SDFZOJ]1069:树上统计

    神题...std丑的不行. 我们可以发现i->i+1的边被覆盖过i×(n-i)次. 因为以1->i为左端点,以i+1->n的为右端点,i->i+1都将被覆盖这么多次. 然后从1 ...

  10. SOA架构设计的案例分析

    面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来.接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台. ...