[SGU]140. Integer Sequences

本文介绍了一道数论题目的解题思路与实现代码。通过分析得出结论:对于数列A和X,在X未知的情况下,可通过求A序列的最大公约数并运用扩展欧几里德算法解决特定方程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Analysis

   (先吐槽一下自己,AC了好几个月才写题解,题目都忘了……) 一道数论方面的题目(话说那时似乎往dp那儿想了很久啊……)。考虑x和y两个数,ax+by能够组成gcd(x,y)的所有倍数。推广到n个数的情形就是a[1]*x[1]+a[2]*x[2]+...+a[n]*x[n]能够组成x[1],x[2],...,x[n]的最大公约数的任意倍数。那么题目中A和X两个数列,由于X是未知的数列,所以应用上述结论,求出A[1],A[2],...,A[n]的最大公约数,然后利用扩展欧几里德解个方程逆着推回去就可以了。

Accepted Code

var
    t,a,x:array[0..110] of longint;
    n,p,b,i,k,r,s:longint;

function ex_gcd(x,y:longint;var a,b:longint):longint;
begin
    if y=0 then
    begin
        a:=1;
        b:=0;
        ex_gcd:=x;
        exit;
    end;
    ex_gcd:=ex_gcd(y,x mod y,b,a);
    b:=b-x div y*a;
end;

begin
    readln(n,p,b);
    for i:=1 to n do
    begin
        read(a[i]);
        a[i]:=a[i] mod p;
        if a[i]=0 then
            a[i]:=p;
    end;
    t[1]:=a[1];
    for i:=2 to n do
        t[i]:=ex_gcd(t[i-1],a[i],r,s);
    for k:=0 to p-1 do
        if t[n]*k mod p=b then
             break;
    if t[n]*k mod p=b then
    begin
        writeln('YES');
        for i:=n downto 2 do
        begin
            s:=ex_gcd(t[i-1],a[i],r,x[i]);
            x[i]:=x[i]*k mod p;
            k:=r*k mod p;
            if k=0 then
                k:=p;
        end;
        x[1]:=k;
        for i:=1 to n do
            while x[i]<0 do
                inc(x[i],p);
        for i:=1 to n-1 do
            write(x[i],' ');
        writeln(x[n]);
    end
    else
        writeln('NO');
end.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值