1. 程式人生 > >AC Codeforces Round #499 (Div. 2) E. Border 擴充套件歐幾里得

AC Codeforces Round #499 (Div. 2) E. Border 擴充套件歐幾里得

沒想出來QAQ....QAQ....
對於一般情況,我們知道 ax+by=gcd(a,b)ax+by=gcd(a,b) 時方程是一定有解的。
如果改成 ax+by=cax+by=c 的話該方程有解當且僅當 cc % gcd(a,b)==0gcd(a,b)==0
這個結論在大於2個個未知數的時候也是成立的,即對於:
a1x1+a2x2+a3x3+......anxn=gcd(a1,a2,a3,...an)a_{1}x_{1}+a_{2}x_{2}+a_{3}x_{3}+......a_{n}x_{n}=gcd(a_{1},a_{2},a_{3}, ...a_{n})

是成立的。
在原題中,我們要求的是 a1x1+a2x2+a3x3+......anxna_{1}x_{1}+a_{2}x_{2}+a_{3}x_{3}+......a_{n}x_{n}\equiv m(modm(mod k)k)mm 的解集。
那麼我們就可以先將式子轉化為 a1x1+a2x2+a3x3+......anxnbk=ma_{1}x_{1}+a_{2}x_{2}+a_{3}x_{3}+......a_{n}x_{n}-bk=m

根據擴充套件歐幾里得定理,mm 存在當且僅當 mmgcd(a1...an,k)gcd(a_{1}...a_{n},k) 的整數倍,我們就現將 gcd(a1...an,k)gcd(a_{1}...a_{n},k) 求出,並分別乘以 2,3,4...2,3,4... 結果大於等於 kk 時停止即可。
Code:

#include<cstdio>
using namespace std;
inline int gcd(
int a,int b) { return b == 0 ? a : gcd(b, a % b); } int main() { int n,k; scanf("%d%d",&n,&k); int m = k; for(int i = 1;i <= n; ++i) { int a; scanf("%d",&a); m = gcd(m, a); } printf("%d\n",k / m); int cnt = 0; while(cnt < k) { printf("%d ",cnt); cnt += m; } return 0; }