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)a
{
	ll c;
	while(b!=0)//不能写成a%b,因为一开始b有可能是0.
	{
		c=a%b;
		a=b;
		b=c;
	}
	return a;
}
发布了34 篇原创文章 · 获赞 0 · 访问量 792

猜你喜欢

转载自blog.csdn.net/aezakmias/article/details/104679841