当我拿到这个题目的时候 我没有多想(首先样例输出为什么是67??????麻烦严谨一点)就直接跳过了
但事实上这个题目如果你只要会GCD和LCM就一定能够写出来
gcd模板:
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
这个就是求两个数的最大公因数!(底层用到的是辗转相除法,时间复杂度为logN);
lcm模板:
int lcm(int a,int b){
return a*b/gcd(a,b);
}
最小公倍数很好理解 就是一个数学知识
那么来看这道题目:
暴力想法是 枚举所有数的lcm 再用gcd去做
这样时间复杂度必然爆(首先枚举两个数就一定会超时O(n^2))
那么我们一定要缩小时间复杂度到nlogn以下(基于是后面压轴题 我一开始的想法很复杂)
我就会用前缀+二分的思想
那么前缀怎么做呢?????或许lcm有类似于前缀的写法 使得到时候求一个区间只需要o(1)复杂度.....
好像又不是这么一回事 因为他并不是要我们求区间。。。而是两个数的差值 最后其实这是一个最简单的数学问题:真是服了。。。
直接上代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int a[N];
int n;
int gcd(int a,int b)//求两个数的最大公约数
{
return b?gcd(b,a%b):a;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int t=a[1];
for(int i=2;i<=n;i++)
{
t=gcd(t,a[i]);//求前i个数的最大公约数
}
cout<<t<<endl;
return 0;
}
根本不需要最小公倍数。。。