公因子(gcd性質)

公因子(gcd性質)

傳送門

思路:

gcdgcd性質:gcd(a,b)=gcd(a,ba)gcd(a,b)=gcd(a,b-a)

推廣:gcd(a1,a2,,an)=gcd(a1,a2a1,,anan1)gcd(a_1,a_2,\dots,a_n)=gcd(a_1,a_2-a_1,\dots,a_n-a_{n-1})

所以此題的gcd(a2a1,,anan1)gcd(a_2-a_1,\dots,a_n-a_{n-1})gcdgcd不能改變了,所以此題的ans=gcd(a2a1,,anan1)ans=gcd(a_2-a_1,\dots,a_n-a_{n-1})

同時又要使a1a_1滿足有因子ansans,所以x=(ansa1%ans)%ansx=(ans-a_1\%ans)\%ans

這樣就能取最小的xx

另外此題有個坑,差分數組可能有負數,會發生除0錯誤的情況,取一下絕對值即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
ll a[N];
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=n;i>1;i--) a[i]=abs(a[i]-a[i-1]);
    ll ans=0;
    for(int i=2;i<=n;i++) ans=gcd(ans,a[i]);
    printf("%lld %lld\n",ans,(ans-a[1]%ans)%ans);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章