公因子

链接:https://ac.nowcoder.com/acm/contest/6112/C
来源:牛客网

公因子
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
牛妹是一个喜欢公因子的女孩子。
定义 n 个整数 a_1, a_2, \ldots, a_na
1

,a
2

,…,a
n

的 \gcdgcd 为最大的正整数 p 满足对于所有 1\le i\le n1≤i≤n,p 整除 a_ia
i


牛妹有一个长度为 n 的整数序列 a_1, a_2, \ldots , a_na
1

,a
2

,…,a
n

。她希望能求出一个非负整数 x,使得 a_1 + x, a_2 + x, \ldots , a_n + xa
1

+x,a
2

+x,…,a
n

+x 的 \gcdgcd 最大。
牛妹不满足于只求出这个最大的 \gcdgcd,所以她希望你还能帮她求出在满足 \gcdgcd 最大时最小的 x。
输入描述:
第一行一个整数 n\ (2\le n\le 10^6)n (2≤n≤10
6
),表示牛妹的序列长度。
第二行 n 个整数 a_1, a_2, \ldots , a_n\ (-10^{18}\le a_i\le 10^{18})a
1

,a
2

,…,a
n

(−10
18
≤a
i

≤10
18
),表示牛妹的序列。
输入保证存在最大的 \gcdgcd。
输出描述:
输出一行两个整数,分别表示最大的 \gcdgcd 和满足 \gcdgcd 最大时最小的 x。
示例1
输入
复制
3
-3 1 3
输出
复制
2 1

啊,我真是又菜又爱写啊。
首先我们需要知道gcd的一些性质。gcd(x,y,z,k)=gcd(x,y-x,z-y,k-z)
可见对所有数+x,是不影响后面差分的值的。所以最大的gcd就是除了第一个的后面的差分数组的gcd,然后x呐,就是将x变成gcd的倍数的最小值。
写文章也是记录自己学习经历,积累知识的。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-10;
int n;
ll a[maxn],dif[maxn];
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
signed main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        dif[i]=a[i]-a[i-1];
    }
    ll x=a[1],y=0;
    for(int i=2;i<=n;i++){
        y=gcd(y,abs(dif[i]));
    }
    printf("%lld %lld\n",y,((y-x)%y+y)%y);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值