xtuoj 公共的数
公共的数
题目

思路
xi+1 = axi + b,当 a ==1
时,xi+1 - xi = b,后一项比前一项多b
,即x
数列构成等差数列,且首项是0
,那么很容易知道x
数列将全部都是b
的倍数。同理,当c == 1
时,y
数列也构成一个等差数列,y
数列将全部都是d
的倍数。当一次项系数不是1
时,不构成等差数列,就是个一般数列。
显然可以分为以下四类
1.x、y
都是等差数列
2.x
是等差,y
不是等差
3.x
不是等差,y
是等差
4.x、y
都不是等差
注意这里首项是零,所以构成等差的话,数列一定是公差的倍数。
对于都是等差的情况,那么公共的数就是b
和d
的公共的倍数,那么个数怎么判断呢,只需要用N/lcm(b,d)
即可,其中lcm(b,d)
是b
和d
的最小公倍数。
对于一个是等差,一个不是等差的情况,我们只需要枚举不是等差的项,判断其是否存在于等差数列中,这里只需取余公差等于0
,则判定其是等差数列中的项,即公共项ans++
。
对于都不是等差的项,只能依次枚举x
数列中的每个数,看其是否存在于y
中,当在y
中找到x
时,不可能再找到别的y
使其等于当前的x
了,因为数列是递增的,那么就跳出y
数列,继续枚举下一个x
。
代码里面要说的几个点,当需要枚举y数列时,采用while(y<=N)
,这是因为题目要求公共的数在[1,109]之间,这里N我提前设置好了为109,什么时候我们可以提前终止循环,当cy>N
时,那么cy+d
必然>N
,但是为了防止整数溢出,我们写成y>N/c
。
有人可能会问为什么不写cy+d>N
呢,这是因为cy+d>N
就是你下一个y>N
,那么其实就是while
的条件判断,所以这里没必要了。
之后我们在把下一个y
的值赋值给当前这个y
,也就是进行下一个y
的判断。
当两个数列都不是等差数列时,我们在y
数列中找到对应相等的x
之后就可以跳出循环了,这是因为我们的y
数列是递增数列,后续不可能再存在与当前x
相等的y
了。
代码
#include<stdio.h>
#define N 1000000000int gcd(int a,int b