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;
}
posted @ 2018-10-05 12:01  EM-LGH  阅读(171)  评论(0编辑  收藏  举报