一道扩展欧几里得的好题。
由于有对
P
取模,于是可以表示为
对于
A1X1+A2X2
,我们可以求出
A1X1+A2X2=gcd(A1,A2)
的
X1
、
X2
,存入X数组中,再把
gcd(A1,A2)
当作新的元素,于是方程变为:
k∗gcd(A1,A2)+A3X3+...+AnXn+PQ=B
,我们再对
gcd(A1,A2),A3
同样进行上述操作,求出
k
、
再把
gcd(A1,A2,A3...An)
与
P
进行同样的操作,同时把所有解乘上
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
inline int read()
{
int x = 0, f = 1, t = getchar();
while(t < '0' || t > '9') {
if(t == '-') f = -1;
t = getchar();
}
while(t >= '0' && t <= '9') {
x = (x<<1) + (x<<3) + t - '0';
t = getchar();
}
return x * f;
}
const int maxn = 105;
int n, P, B, A[maxn], x[maxn];
void gcd(int a, int b, int &d, int &x, int &y)
{
if(b == 0) d = a, x = 1, y = 0;
else gcd(b, a % b, d, y, x), y -= x*(a/b);
}
void init()
{
n = read(), P = read(), B = read();
for(int i = 1; i <= n; ++i)
A[i] = read() % P; //remember '%' !
}
void work()
{
register int i, j, a, b, GCD = A[1];
x[1] = 1;
for(i = 2; i <= n; ++i) {
gcd(GCD, A[i], GCD, a, b);
for(j = 1; j < i; ++j) x[j] = x[j] * a % P;
x[i] = b;
}
gcd(GCD, P, GCD, a, b);
if(B % GCD == 0) {
puts("YES");
for(i = 1; i <= n; ++i) {
x[i] = x[i] * a * B / GCD % P;
x[i] = (x[i] + P) % P;
}
for(i = 1; i <= n; ++i)
printf("%d ", x[i]);
}
else puts("NO");
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
init();
work();
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}