P1072 [NOIP2009 提高组] Hankson 的趣味题

题目描述

Hanks 博士是 BT(Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。

今天在课堂上,老师讲解了如何求两个正整数 c1​ 和 c2​ 的最大公约数和最小公倍数。现在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0​,a1​,b0​,b1​,设某未知正整数 xx 满足:

  1. x 和 a0​ 的最大公约数是 a1​;

  2. x 和 b0​ 的最小公倍数是 b1​。

Hankson 的“逆问题”就是求出满足条件的正整数 xx。但稍加思索之后,他发现这样的 x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮助他编程求解这个问题。

输入格式

第一行为一个正整数 n,表示有 n 组输入数据。接下来的n 行每行一组输入数据,为四个正整数 a0​,a1​,b0​,b1​,每两个整数之间用一个空格隔开。输入数据保证 a0​ 能被 a1​ 整除,b1​ 能被 b_0b0​ 整除。

输出格式

共 n 行。每组输入数据的输出结果占一行,为一个整数。

对于每组数据:若不存在这样的 x,请输出 0,若存在这样的 x,请输出满足条件的 x 的个数;

输入输出样例

输入 #1

2 
41 1 96 288 
95 1 37 1776 

输出 #1

6 
2

说明/提示

【样例解释】

第一组输入数据,x 可以是 9,18,36,72,144,288,共有 6 个。

第二组输入数据,x 可以是 48,1776,共有 2 个。

【数据范围】

  • 对于 50\%50% 的数据,保证有 1≤a0​,a1​,b0​,b1​≤10000 且 n≤100。
  • 对于 100\%100% 的数据,保证有 1≤a0​,a1​,b0​,b1​≤2×10^{9} 且 n≤2000。

题解

没错我不是来宣传正解的,我是来说一种毒瘤解法的 。

哦哦,如果你不想看讲基本做法。你可以向下翻。

嗯,其实遇到这种单纯的gcd  or  lcm的题,我们都可以用一种比较简单的方法分析:唯一分解定理。

嗯,是整数域的唯一分解,不是多项式域的唯一分解。

那么其实其他的大佬已经解释得很清楚了,关于这种解法,大部分来讲都是先筛出数据范围上限n​即可。但是有个Bug就是对于每个合数k,都最多有一个质因子是大于k​的由于数据范围过大窝萌没法直接筛,而我正是解决了这个问题(虽然有点慢).

我们思考对于a0​和a1​而言,假设gcd(x,a0​)=a1​

那么我们会有比较浅显的结论:

若a0​=i=1∏m​pici​​  ,  x=i=1∏n​pidi​​

那么

a1​=i=1∏max(m,n)​pimin(ci​,di​)​

那我们反着考虑,对于他们的 gcd——a1​ 里的 pi​ 来讲,要么是a0​中的,要么是x中的。换句话说,如果ci​=min(ci​,di​),那么di​只需要≥ ci​即可,也就是说di​可以在区间 [ci​,∞) 上随便取,我们现在称这个x为自由未知数(free known−number),称这个区间为自由区间(free ranges)

而如果不一样,就只可能是 ci​>min(di​,ci​),此时没有任何取法,只有可能是 di​=min(di​,ci​),所以就只能有一种选法,我们现在称这个x为非自由未知数(unfree uknown−number)

同理,lcm那部分也一样。

但是这个地方需要注意的是,我们需要考虑2^{2}种不同情况:

1、两个方程的x均非自由,那么如果不同的话就会无解。

2&3、gcd或者lcm中有一个非自由,我们需要判断这个非自由的解是否是在另一个的自由区间内,不在就是不合法。

4、都是自由的,那么就做个差留到最后乘法原理。

代码大概长这样:

​
inline void Linearity(){T = qr() ;Chk[1] = Chk[0] = 1 ;for (i = 2 ; i <= MAX ; ++ i){if (!Chk[i]) P[++ P[0]] = i ;for (j = 1; j <= P[0] && i * P[j] <= MAX ; ++ j){Chk[i * P[j]] = 1 ;if (i % P[j] == 0) break ;}}
}
inline void work(int ST, int ED){for(i = ST; i <= ED ; ++ i){N1 = N2 = N3 = N4 = 0 ;while (!(A0 % P[i])) A0 /= P[i], ++ N1 ;while (!(A1 % P[i])) A1 /= P[i], ++ N2 ;while (!(B0 % P[i])) B0 /= P[i], ++ N3 ;while (!(B1 % P[i])) B1 /= P[i], ++ N4 ;if (N1 > N2 && N3 < N4){if (N2 == N4) A[i] = B[i] = 1 ;else {mark = 0; break ;}continue ;}if (N1 > N2){if (N4 >= N2) A[i] = B[i] = N2 ;else {mark = 0; break ;}continue ;}if (N3 < N4){if (N4 >= N2) A[i] = B[i] = N3 ;else {mark = 0; break ;}continue ;}else {if (N4 >= N2) A[i] = N2, B[i] = N4 ;else {mark = 0; break ;}}}
}​

那么接下来的问题就是该怎么确定最后一个质因子。有一个很显然的做法是由于是最后一个质因子,所以我们只需要判断一下分解完质因数每一个是不是1即可,不是1的话,那就肯定是未筛到的,我们直接让他加入prime数组即可。哦,对,还需要再筛一遍,详情看代码即可。

​
#include <cstdio>
#include <bitset>
#include <iostream>
#define MAX 45000
#define ll long longusing namespace std ;
bitset <MAX> Chk ; int A0, A1, B0, B1 ;
int Ans, T, i, j, P[MAX >> 2] ; bool mark ;
int N1, N2, N3, N4, A[MAX >> 2], B[MAX >> 2], Txt ;inline int qr(){int k = 0 ; char c = getchar() ;while(!isdigit(c)) c = getchar() ;while(isdigit(c)) k = (k << 1) + (k << 3) + c - 48, c = getchar() ;return k ;
}
inline void Linearity(){T = qr() ;Chk[1] = Chk[0] = 1 ;for (i = 2 ; i <= MAX ; ++ i){if (!Chk[i]) P[++ P[0]] = i ;for (j = 1; j <= P[0] && i * P[j] <= MAX ; ++ j){Chk[i * P[j]] = 1 ;if (i % P[j] == 0) break ;}}
}
inline void work(int ST, int ED){for(i = ST; i <= ED ; ++ i){N1 = N2 = N3 = N4 = 0 ;while (!(A0 % P[i])) A0 /= P[i], ++ N1 ;while (!(A1 % P[i])) A1 /= P[i], ++ N2 ;while (!(B0 % P[i])) B0 /= P[i], ++ N3 ;while (!(B1 % P[i])) B1 /= P[i], ++ N4 ;if (N1 > N2 && N3 < N4){if (N2 == N4) A[i] = B[i] = 1 ;else {mark = 0; break ;}continue ;}if (N1 > N2){if (N4 >= N2) A[i] = B[i] = N2 ;else {mark = 0; break ;}continue ;}if (N3 < N4){if (N4 >= N2) A[i] = B[i] = N3 ;else {mark = 0; break ;}continue ;}else {if (N4 >= N2) A[i] = N2, B[i] = N4 ;else {mark = 0; break ;}}}
}
int main(){freopen("son.in", "r", stdin) ;freopen("son.out", "w", stdout) ;Linearity() ;while(T --){Ans = 1, mark = 1 ;A0 = qr(), A1 = qr(), B0 = qr(), B1 = qr() ;work(1, P[0]) ;if (A0 != 1 || A1 != 1 || B0 != 1 || B1 != 1){Txt = P[0] + 1 ;if (B1 != 1) P[++ P[0]] = B1 ;if (A1 != 1 && A1 != B1) P[++ P[0]] = A1 ;if (A0 != 1 && A0 != B1 && A0 != A1) P[++ P[0]] = A0 ;if (B0 != 1 && B0 != B1 && B0 != A1 && B0 != A0) P[++ P[0]] = B0 ;work(Txt, P[0]) ;}for(i = 1; i <= P[0] && mark ; ++ i) Ans *= (B[i] - A[i] + 1) ;if (!mark) putchar('0'), putchar('\n') ;else printf("%d\n", Ans) ;}
}​

最后还有彩蛋哦:

1、这个题中的关键代码,就是work函数是在作者事先考虑清楚,事中如同做梦,事后不可思议的情况下写出来的……也就是说当时写代码的时候码力突然增强了一个量级

2、关于什么自由不自由的定义……哈哈哈哈那只是我的突发奇想而已~~不是故意哲学!不是!~~但是你会发现以下的文字阐述确实会简练好多啊

3、其实你如果去不找另一个比较大的质数,也是可以得90分的!从loj的数据来看,前面的测试点一路顺风,只有最后一个测试点是专门卡这一点的,因为出现了好多行答案不相同的情况

4、其实我觉得我最后的操作是跟AlphaGo动态学习处理信息有点异曲同工之处的,所以为了这个必须来写题解! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/57115.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小学奥数与信奥

小学奥数与信奥 题目 3. 把4分拆成几个数相加的形式(0不考虑作为加数)&#xff0c;有多少种不同的分拆方式&#xff1f; 把5分拆成几个数相加的形式(0不考虑作为加数)&#xff0c;有多少种不同的分拆方式&#xff1f; 把6分拆成几个数相加的形式(0不考虑作为加数)&#xff0c…

站长在线经典Python题:使用Python编程思想解决鸡兔同笼的问题的4种方法

欢迎你来到站长在线的Python题库&#xff0c;鸡兔写完Python教程以后&#xff0c;还是来一个Python的题目吧&#xff01;想来想去&#xff0c;还是写一个经典的题目为好&#xff0c;作为本栏目的第一个题目。我就想到了比较热门的题目《鸡兔同笼的问题》&#xff0c;本文不是用…

Qt常用的按钮控件编程(五)-- QCommandLinkButton 按钮

文章目录 前言7、QCommandLinkButton按钮7.1 例程功能和程序执行效果7.2 生成项目7.3 添加资源文件7.4 代码编辑7.4.1 修改项目文件 _radiobutton.pro7.4.2 修改 main.cpp7.4.3 修改 widget.h7.4.4 修改 widget.cpp 7.5 切换Kit&#xff0c;获得运行在不同系统中的运行的执行文…

【python】tkinter程序打包成exe可执行文件相关知识点记录

打包流程&#xff1a; 进入带打包的文件夹目录&#xff0c;输入“cmd” 在cmd对话框中输入 pyinstaller -F -w -i 【exe图标位置&#xff08;ico文件&#xff09;】【程序入口文件】 pyinstaller -F -w -i i.ico test.py 具体如图&#xff0c;图片摘自python利用pyinstaller打…

chatgpt赋能python:Python如何进行P图——探索Python图像处理库的可能性

Python如何进行P图——探索Python图像处理库的可能性 介绍 随着数字化时代的到来&#xff0c;图像处理已不再是专业领域的专属&#xff0c;许多人也开始接触和学习图像处理。我们常见的图像处理软件有Photoshop和GIMP等&#xff0c;而在Python编程领域中&#xff0c;也有很多…

面向对象程序设计 C++总结笔记(1)

面向对象程序设计 学习方法 理解基本原理掌握程序设计方法加强动手实践 课程目标 理解面向对象程序设计的基本原理&#xff0c;掌握面向对象技术的基本概念和封装性、继承性和多态性&#xff0c;能够具有面向对象程序设计思想。掌握C语言面向对象的基本特性和C语言基础知识&…

深度学习实战5-卷积神经网络(CNN)中文OCR识别项目

文章目录 一、前期工作 导入库图片生成函数导入数据生成数据集函数 二、CNN模型建立 三、训练模型函数 四、训练模型与结果 五、验证 大家好&#xff0c;我是微学AI&#xff0c;今天给大家带来一个利用卷积神经网络&#xff08;CNN&#xff09;进行中文OCR识别&#xff0c;…

7个成功的DTC品牌出海营销策略,提高海外客户的忠诚度!

关键词&#xff1a;DTC品牌出海、DTC营销、客户忠诚度 近年来&#xff0c;普通消费者关心的事情发生了巨大变化。 60% 的消费者会特意从品牌而不是第三方零售商处购买。 从大型零售商处购买再成为主流。人们希望与他们关心并感到关心的品牌建立关系。他们希望支持独立企业并找到…

Cat.1热度居高不下,利尔达 NT26E系列模组带来更多新选择

2021年全球Cat.1处于爆发期&#xff0c;出货量达到1.2亿&#xff0c;仅在中国市场上&#xff0c;Cat.1出货量就达到了1.1亿。据近日市场研究公司Counterpoint最新的发布全球蜂窝物联网芯片跟踪报告&#xff0c;2021年第四季度&#xff0c;4G Cat.1出货量同比增长154%。今年的市…

Cat.1模组再添新选择,利尔达推出NT26U提供多元应用思路

Cat.1因模组成熟度高且可复用现有的LTE资源而广受欢迎&#xff0c;它不但成本低&#xff0c;还能在短时间内形成规模效应。随着2G/3G的加速退网&#xff0c;Cat.1作为中低速率应用场景中最适合保障通信能力的网络之一更是水涨船高。 基于展锐的Cat.1模组 作为LTE网络的“低配版…

短信接收流程

Android 短信接收流程 Android S 短信接收流程 Android 12 短信接收流程 指路 -> 短信发送流程 流程图

开题报告PPT怎么制作

毕业设计答辩的首要环节就是前期答辩&#xff0c;也叫作开题汇报答辩&#xff0c;主要内容是对后期设计制作的规划及时间安排&#xff0c;同时还有设计要达到什么目的效果&#xff0c;预测在制作工程中可能遇到的问题并且提出这些问题的解决方案&#xff0c;开题报告汇报时以PP…

springboot+微信小程序的点餐系统(开题报告+论文+答辩PPT+源码)

技术架构 SprongBootMysql微信小程序 简介 本点餐小程序是使用Java/JavaScript编程语言开发的&#xff0c;存储数据方面则用到了MySQL数据库。顾客可以使用小程序扫码功能扫描餐厅桌角的二维码就座&#xff0c;也可以点击排号等位由后台工作人员安排就座&#xff1b;通过首页…

毕业论文学术报告答辩开题报告PPT模板

模板介绍 毕业论文学术报告答辩开题报告PPT模板。一套论文答辩幻灯片模板&#xff0c;内含黑色,红色多种配色&#xff0c;风格设计&#xff0c;动态播放效果&#xff0c;精美实用。 希望下面这份精美的PPT模板能给你带来帮助&#xff0c;温馨提示&#xff1a;本资源使用PPT或…

python图片分享平台毕业设计开题报告

本文给出的python毕业设计开题报告&#xff0c;仅供参考&#xff01;&#xff08;具体模板和要求按照自己学校给的要求修改&#xff09; 选题目的和意义 目的&#xff1a;本课题主要目标是设计并能够实现一个基于web网页的图片分享平台&#xff0c;整个网站项目使用了B/S架构…

高校通用论文开题报告PPT模板

模板介绍 高校通用论文开题报告PPT模板。一套开题报告幻灯片模板&#xff0c;内含青色,红色多种配色&#xff0c;风格设计&#xff0c;动态播放效果&#xff0c;精美实用。 希望下面这份精美的PPT模板能给你带来帮助&#xff0c;温馨提示&#xff1a;本资源使用PPT或PPTX等格…

计算机开题报告万能模板,计算机开题报告ppt模板

PPT内容 这是计算机开题报告ppt模板&#xff0c;包括了课题研究的意义和目的&#xff0c;论文提纲&#xff0c;研究的预期目标及主要特点及创新点&#xff0c;研究方法和途径等内容。 基于NS的无线网络的AODV路由协议仿真测试与性能分析 毕业论文开题报告 指导老师&#xff1a;…

chatglm+tesla m40低成本部署

chatglmtesla m40部署 tesla m40安装BIOS设置驱动下载并安装验证安装并切换WDDM模式 chatglm安装环境安装加载模型CUDA安装Torch安装源码修改 成功结果展示常见问题 本机配置 i5 13600k ,主板是微星760 bomer tesla m40安装 Tesla M40 24G实际上是计算卡&#xff0c;不是显卡&…

Win11 的这 19 个新功能,你都用上了吗?

Windows 11 是 Windows 的新版本&#xff0c;现在正在向受支持的 PC 推出多项新功能和改进。 Windows 11 于 10 月 5 日开始推出&#xff0c;微软也发布了 Windows 11 ISO 镜像。与之前的 Windows 10 更新不同&#xff0c;这个新的操作系统专注于面向消费者的功能和改进&#x…

使用WinINet和WinHTTP实现Http访问

Http访问有两种方式&#xff0c;GET和POST&#xff0c;就编程来说GET方式相对简单点&#xff0c;它不用向服务器提交数据&#xff0c;在这个例程中我使用POST方式&#xff0c;提交数据value1与value2&#xff0c;并从服务器得到他们的和&#xff08;value1 value2&#xff09;…