解模意义下的方程
可以视为解不定方程
A1∗x1+A2∗x2+A3∗x3+……+An∗xn+P∗xn+1=B
用欧几里得扩展算法
二元情形:
设a>b。
1,显然当 b=0 时,gcd(a,b)=a 。此时 x=1,y=0;
2,a , b <> 0 时,
设 a∗x1+b∗y1=gcd(a,b)
b∗x2+(a mod b)∗y2=gcd(b,a mod b)
根据朴素的欧几里德原理有 gcd(a,b)=gcd(b,amodb)
则:a∗x1+b∗y1=b∗x2+(a mod b)∗y2
即:a∗x1+b∗y1=b∗x2+(a−[a/b]∗b)∗y2=a∗y2+b∗x2−[a/b]∗b∗y2
也就是a∗x1+b∗y1==a∗y2+b∗(x2−[a/b]∗y2)
根据恒等定理得:x1=y2 , y1=x2−[a/b]∗y2;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
多元情形:
gcd(a1,a2,……,ai−1)∗x+ai∗y=gcd(a1,a2,……,ai−1,ai)
可以用二元方法解出x,y
原方程中Xi=y,Xj=Xj∗x,j<i
最后要注意把X都变成非负整数
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<iostream>
#include<algorithm>
const int MAXN = 105;
int ax[MAXN] = {0};
int A[MAXN] = {0};
int N,P,B;
int super_gcd(int a,int b,int &x,int &y)
{
if(!b)
{
x = 1;
y = 0;
return a;
}
else
{
int ret = super_gcd(b,a%b,x,y);
int tmp = x;
x = y;
y = tmp - a/b*y;
return ret;
}
}
int main()
{
int gcd;
#ifndef ONLINE_JUDGE
freopen("sgu140.in","r",stdin);
freopen("sgu140.out","w",stdout);
#endif
scanf("%d%d%d",&N,&P,&B);
for(int i = 1; i <= N; i++)
{scanf("%d",&A[i]);A[i] %= P;}
ax[1] = 1 , gcd = A[1]; A[N+1] = P;
for(int i = 2; i <= N+1; i++)
{
int x , y;
gcd = super_gcd(gcd , A[i] , x , y);
ax[i] = y;
for(int j = 1 ; j < i; j++)
ax[j] *= x,ax[j] %= P;
}
if(B%gcd)
puts("NO");
else
{
int tmp = B/gcd;
for(int i = 1; i <= N; i++)
{ax[i] *= tmp; ax[i] = (ax[i]%P + P)%P;}
puts("YES");
for(int i = 1; i <= N; i++)
printf("%d ",ax[i]);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}
版权声明:本文为博主原创文章,未经博主允许不得转载。