最大公约数(gcd.pas/c/cpp) TL:1S ML:256MB
【Description】
有N个整数,kAc会对它们做Q次修改。
每次修改指的是对所有数加一个整数(可正可负)
每修改一次后,他想知道当前所有数的最大公约数是多少。
【Input】
第一行两个整数N, Q
接下来N行,每行一个整数,表示这N个数的初始值。
接下来Q行,每行一个整数,表示这Q个操作。第i个数表示这一次操作是增加了多少。
【Output】
共Q行,表示进行完第i次操作后,所有数的最大公约数
【Sample Input】
3 2
1 -5 7
-1
1
【Sample Output】
6
1
【Hint】
对于40%:N, Q <= 1000
对于70%:N, Q <= 40000
对于100%:N, Q <= 100000,所有数的绝对值始终小于等于10^16
【Description】
有N个整数,kAc会对它们做Q次修改。
每次修改指的是对所有数加一个整数(可正可负)
每修改一次后,他想知道当前所有数的最大公约数是多少。
【Input】
第一行两个整数N, Q
接下来N行,每行一个整数,表示这N个数的初始值。
接下来Q行,每行一个整数,表示这Q个操作。第i个数表示这一次操作是增加了多少。
【Output】
共Q行,表示进行完第i次操作后,所有数的最大公约数
【Sample Input】
3 2
1 -5 7
-1
1
【Sample Output】
6
1
【Hint】
对于40%:N, Q <= 1000
对于70%:N, Q <= 40000
对于100%:N, Q <= 100000,所有数的绝对值始终小于等于10^16
在这里,我们认为任意非负整数x跟0的最大公约数都是x
【题解】
若一个数于这几个数都是因数,则它一定是所有数之间差的公因数;
所以把它们两两做差(相邻的做即可),求出这些差值的最大公因数,然后每次只更新a[1],并与它再取公因数,即可。
代码附上
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<string.h>
using namespace std;
int n,m;
int gcd(int a,int b)
{
if(a==0)
return b;
if(b==0)
return a;
if(a%b==0)
return b;
else
return gcd(b,a%b);
}
int g[100050];
int main()
{
//freopen("gcd.in","r",stdin);
//freopen("gcd.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&g[i]);
}
int yu=abs(g[2]-g[1]);
for(int i=3;i<=n;i++)
{
yu=gcd(yu,abs(g[i]-g[i-1]));
}
int hj;
for(int i=1;i<=n;i++)
{
scanf("%d",&hj);
g[1]+=hj;
int ans=gcd(yu,abs(g[1]));
cout<<ans<<endl;
}
}