sgu 140 Integer Sequences

140. Integer Sequences

time limit per test: 0.5 sec.
memory limit per test: 4096 KB

A sequence Ais called an integer sequence of length N if all its elementsA1A2 .. AN are non-negative integers less than2000 000 000. Consider two integer sequences of length N,Aand X. The result of their multiplication (A*X) is an integernumber R=A1*X1 + A2*X2 +.. + AN*XN. Your task is to solve the equationA*X=B(mod P), given the integer sequenceA and the integer numbersBand P.

Input

The first line containsthe integer numbers N (1<=N<=100) - the length of theinteger sequences - P (1<=P<=10 000) and B (0<=B<=P-1).The second line contains the elements of the sequence A, separatedby blanks:A1 A2 .. AN.

Output

You should print oneline containing the word "YES" if there exists at least one integersequence X which is a solution to the equation, or print"NO"otherwise. If the answer is "YES", the next line should containNnon-negative integers separated by blanks: X1 X2.. XN.

Sample Input #1

2 7 4
7 3

Sample Output #1

YES
0 6

Sample Input #2

3 10 1
2 4 6

Sample Output #2

NO



多元的一次模方程。

我们假设 g[i] 表示 gcd(a[1],a[2],......,a[i]) ;

如果解是x1 x2 x3 ... xn

先求出 g[n] *X + p*Y = b的解

然后求出

g[n-1]*X1+a[n]*xn = g[n]*X的解,

依次递推求解即可。


贴代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
#include<vector>
#include<cstdlib>

#define inf 0xfffffff
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define FOR(a,b) for(int a=1;a<=(b);(a)++)
#define BUG puts("here");
#define int long long

using namespace std;
int const nMax = 1010;
int const base = 10;
typedef long long LL;
typedef pair<LL,LL> pij;

//    std::ios::sync_with_stdio(false);

int p;
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int gcd(int a,int b,int &x,int &y){
    if(b==0){
        x=1;y=0;return a;
    }
    int d=gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int equ(int a,int b,int n,int &x,int &y){
    int d;
    d=gcd(a,n,x,y);
    if(b%d)return 0;
    x*=(b/d);y*=(b/d);
    //x=(x%p+p)%p;
    //y=(y%p+p)%p;
    return 1;
}

int g[nMax],a[nMax],n,b;
int ans[nMax];
main(){
    scanf("%I64d%I64d%I64d",&n,&p,&b);
    for(int i=0;i<n;i++){
        scanf("%I64d",&a[i]);a[i]%=p;
        if(a[i]==0)a[i]=p;
        g[i]=a[i];
        if(i)g[i]=gcd(g[i],g[i-1]);
       // printf("g[%d]=%d\n",i,g[i]);
    }
    int x,y;
    int d=equ(g[n-1],b,p,x,y);
    if(d==0){
        puts("NO");
        return 0;
    }
   // printf("g[n-1]=%lld p=%lld b=%lld d=%lld x=%lld y=%lld \n",g[n-1],p,b,d,x,y);
    for(int i=n-1;i>0;i--){
        d=equ(g[i-1],b=x*g[i],a[i],x,ans[i]);
    //    printf("g[n-1]=%lld p=%lld b=%lld d=%lld x=%lld y=%lld \n",g[i-1],a[i],b,d,x,ans[i]);
        ans[i]=(ans[i]%p+p)%p;
        //BUG
    }
    ans[0]=(x%p+p)%p;
    puts("YES");
    for(int i=0;i<n;i++)printf("%I64d ",ans[i]);
    return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值