AC Codeforces Round #499 (Div. 2) E. Border 扩展欧几里得

没想出来 Q A Q . . . . QAQ....
对于一般情况,我们知道 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) 时方程是一定有解的。
如果改成 a x + b y = c ax+by=c 的话该方程有解当且仅当 c c % g c d ( a , b ) = = 0 gcd(a,b)==0
这个结论在大于2个个未知数的时候也是成立的,即对于:
a 1 x 1 + a 2 x 2 + a 3 x 3 + . . . . . . a n x n = g c d ( a 1 , a 2 , a 3 , . . . a n ) 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}) 是成立的。
在原题中,我们要求的是 a 1 x 1 + a 2 x 2 + a 3 x 3 + . . . . . . a n x n a_{1}x_{1}+a_{2}x_{2}+a_{3}x_{3}+......a_{n}x_{n}\equiv m ( m o d m(mod k ) k) m m 的解集。
那么我们就可以先将式子转化为 a 1 x 1 + a 2 x 2 + a 3 x 3 + . . . . . . a n x n b k = m a_{1}x_{1}+a_{2}x_{2}+a_{3}x_{3}+......a_{n}x_{n}-bk=m
根据扩展欧几里得定理, m m 存在当且仅当 m m g c d ( a 1 . . . a n , k ) gcd(a_{1}...a_{n},k) 的整数倍,我们就现将 g c d ( a 1 . . . a n , k ) gcd(a_{1}...a_{n},k) 求出,并分别乘以 2 , 3 , 4... 2,3,4... 结果大于等于 k k 时停止即可。
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;
}

猜你喜欢

转载自blog.csdn.net/liyong1009s/article/details/82943189
今日推荐