CodeForces 1203C-Common Divisors(欧几里得)
You are given an array a consisting of n integers.
Your task is to say the number of such positive integers x such that x divides each number from the array. In other words, you have to find the number of common divisors of all elements in the array.
For example, if the array a will be [2,4,6,2,10], then 1 and 2 divide each number from the array (so the answer for this test is 2).
Input
The first line of the input contains one integer n (1≤n≤4⋅105) — the number of elements in a.
The second line of the input contains n integers a1,a2,…,an (1≤ai≤1012), where ai is the i-th element of a.
Output
Print one integer — the number of such positive integers x such that x divides each number from the given array (in other words, the answer is the number of common divisors of all elements in the array).
Examples Input
5
1 2 3 4 5
Output
1
Input
6
6 90 12 18 30 18
Output
4
您将得到一个由n个整数组成的数组。
您的任务是说这样的正整数x的数量,以使x将数组中的每个数字相除。 换句话说,您必须找到数组中所有元素的公共除数的数量。
例如,如果数组a为[2,4,6,2,10],则1和2除以数组中的每个数字(因此此测试的答案为2)。
输入值
输入的第一行包含一个整数n(1≤n≤4⋅10^5)-a中的元素数。
输入的第二行包含n个整数a1,a2,…,an(1≤ai≤1012),其中ai是a的第i个元素。
输出量
打印一个整数-这样的正整数x的数量,以使x将给定数组中的每个数字除以整数(换句话说,答案是数组中所有元素的公共除数的数量)。
例子
输入值
5
1 2 3 4 5
输出量
1个
输入值
6
6 90 12 18 30 18
输出量
4
题目大意:
这道题是CF上的题目,意思是给你n个数,求这n个数都能整除的数的数量。比如给12 4 6 8 10,这5个数都能被1 2 除尽,所以最后输出2。
解题思路:
我刚开始是求的这几个数中最小的数,超时了好多次,不过就算是不超时,很显然也是不对的,因为这几个数中最小的数不一定是这几个数的公约数,我是把最小的数当作公约数了,就肯定不对,思路是找到这n个数的最大公约数,因为是最大公约数,所以这个最大公约数的因子数量就是最后要求的数量,用欧几里得求出最大公约数,然后对这个最大公约数分解因子,因为数据范围是1e12,暴力分解肯定TLE,给这个数开个根号,以36为例,开完后是6,能被1整除的一定能被36整除,能被2整除的一定能被18整除,能被3整除的一定能被12整除,所以说开完根号后,如果能被这个范围内的数整除,说明后面一定有对应的数,所以从1遍历到sqrt(最大公约数)就可以,因为ans始终要+=2,所以特判一下,因为36/6=6,ans不需要+=2,所以这里ans–,最后输出ans即可。AC代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false);
ll gcd(ll,ll);
int n;
cin>>n;
ll s=0,num;
for(int i=1;i<=n;i++)
{
cin>>num;
s=gcd(s,num);
}
int ans=0;
ll sq=(ll)sqrt(s);
for(ll i=1;i<=sq;i++)
if(s%i==0)
{
ans+=2;
if(s/i==i)//特判一下边界的情况
ans--;
}
cout<<ans<<endl;
return 0;
}
ll gcd(ll a,ll b)
{
ll c;
while(b!=0)//不能写成a%b,因为一开始b有可能是0.
{
c=a%b;
a=b;
b=c;
}
return a;
}