(解一元线性同余方程组)

转载:

/**********************一般模线性方程组***********************/

同样是求这个东西。。
X mod m1=r1
X mod m2=r2
...
...
...
X mod mn=rn

首先,我们看两个式子的情况
X mod m1=r1……………………………………………………………(1)
X mod m2=r2……………………………………………………………(2)
则有
X=m1*k1+r1………………………………………………………………(*)
X=m2*k2+r2
那么 m1*k1+r1=m2*k2+r2
整理,得
m1*k1-m2*k2=r2-r1
令(a,b,x,y,m)=(m1,m2,k1,k2,r2-r1),原式变成
ax+by=m
熟悉吧?

此时,因为GCD(a,b)=1不一定成立,GCD(a,b) | m 也就不一定成立。所以应该先判 若 GCD(a,b) | m 不成立,则!!!方程无解!!!。
否则,继续往下。

解出(x,y),将k1=x反代回(*),得到X。
于是X就是这两个方程的一个特解,通解就是 X‘=X+k*LCM(m1,m2)
这个式子再一变形,得 X‘ mod LCM(m1,m2)=X
这个方程一出来,说明我们实现了(1)(2)两个方程的合并。
令 M=LCM(m1,m2),R=r2-r1
就可将合并后的方程记为 X mod M = R。

然后,扩展到n个方程。
用合并后的方程再来和其他的方程按这样的方式进行合并,最后就能只剩下一个方程 X mod M=R,其中 M=LCM(m1,m2,...,mn)。
那么,X便是原模线性方程组的一个特解,通解为 X‘=X+k*M。

如果,要得到X的最小正整数解,就还是原来那个方法:

X%=M;
if (X<0) X+=M;

这么一来~~大功告成~~
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
long long a,b,c,n,d;
long long X,Y;
void extend(long long A,long long B,long long &d,long long &x1,long long &y1)
{
    if(B==0)//犯了一个低级失误如果写成long long d的话函数的值传回到主函数
    {
        x1=1;
        y1=0;
        d=A;
        return ;
    }
    extend(B,A%B,d,x1,y1);
    long long temp=x1;
    x1=y1;
    y1=temp-(A/B)*y1;
    return ;
}
int main()
{
    long long a1,r1,a2,r2,i,j;
    while(scanf("%lld",&n)!=EOF)
    {
        bool ifhave=true;
        scanf("%lld%lld",&a1,&r1);
        for(i=2; i<=n; i++)
        {
            scanf("%lld%lld",&a2,&r2);
            a=a1;
            b=a2;
            c=r2-r1;
            extend(a,b,d,X,Y);
            if(c%d)
            {
                ifhave=false;
                break;
            }
            long long t=b/d;
            X=(X*(c/d)%t+t)%t;//最小解
            r1=a1*X+r1;
            a1=a1*(a2/d);
        }
        for(j=i+1; j<=n; j++)
        {
            scanf("%lld%lld",&a2,&r2);
        }
        if(!ifhave)
        {
            printf("-1\n");
            continue;
        }
        printf("%lld\n",r1);
    }
    return  0;
}
时间: 2024-10-14 13:21:15

(解一元线性同余方程组)的相关文章

HDU1573:X问题(解一元线性同余方程组)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1573 题目解析;HDU就是坑,就是因为n,m定义成了__int64就WAY,改成int就A了,无语. 这题就是求解一元线性同余方程组的解满组小于正整数n的数目.最小正整数的解为X=(X*(c/d)%t+t)%t;  X=a1*X+r1;其中X为扩展欧几里得解出来的特解,这m个方程组的循环区间为lcm(a1,a2,a3...am),所以答案为(n-X)/lcm+1; #include <iostream>

HDU3579:Hello Kiki(解一元线性同余方程组)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3579 题目解析:求一元线性同余方程组的最小解X,需要注意的是如果X等于0,需要加上方程组通解的整数区间lcm(a1,a2,a3,...an). 别的就没什么注意的了. #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <math.h&

HDU1573 X问题【一元线性同余方程组】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1573 题目大意: 求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], -, X mod a[i] = b[i], - (0 < a[i] <= 10). 思路: 先求出数组b[]中所有数的最小公倍数lcm,再求解出该一元线性同余方程组在lcm范围内的解为a,题目要 求解x是小于等于N的正整数,则

求解一元线性同余方程组模版

解法:直接上模版. 扩展欧几里德的模版: typedef long long LL; LL ex_gcd(LL a,LL b,LL &x,LL &y) { if(b==0) { x=1; y=0; return a; } LL d=ex_gcd(b,a%b,x,y); LL t=x; x=y; y=t-a/b*y; return d; } 求解一元线性同余方程组模版: LL solve(LL n) { LL a1,r1,a2,r2; LL a,b,c,r,x,y; bool ifhave=

HDU3579 Hello Kiki【一元线性同余方程组】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3579 题目大意: Kiki有X个硬币,她用不同的方式数了N次,每次她把硬币分成大小相等的组,记录每次一组硬币 的个数Mi和数完最后剩余的硬币数Ai.那么问题来了:总共有多少枚硬币? 思路: 典型的一元线性同余方程组X = Ai(mod Mi)求解.题目要求输出最小正整数解,则如果求得同余 方程组的解为0,那么答案就是所有Mi的最小公倍数. AC代码: #include<iostream> #in

POJ2891 Strange Way to Express Integers【一元线性同余方程组】

题目链接: http://poj.org/problem?id=2891 题目大意: 选择k个不同的正整数a1.a2.-.ak,对于某个整数m分别对ai求余对应整数ri,如果 适当选择a1.a2.-.ak,那么整数m可由整数对组合(ai,ri)唯一确定. 若已知a1.a2.-.ak以及m,很容易确定所有的整数对(ai,ri),但是题目是已知a1. a2.-.ak以及所有的整数对(ai,ri),求出对应的非负整数m的值. 思路: 题目可以转换为给定一系列的一元线性方程 x ≡ r1( mod a1

HDU 1573 X问题(一元线性同余方程组)

X问题 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3850    Accepted Submission(s): 1228 Problem Description 求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], -, X mo

POJ 2891 Strange Way to Express Integers(一元线性同余方程组模版题)

题意:给出n个模方程组:x mod ai = ri.求x的最小正值.如果不存在这样的x,那么输出-1. 涉及的数论知识: 对于一般式ax ≡ b(mod m) 当a=1时,两个同余方程就可以合并成一个同余方程 比如对于本题: x mod a1=r1 x mod a2=r2 有不定方程: x=r2+a2*y2 x=r2+a2*y2 联立: a1y1+a2*(-y2)=r2-r1 可以通过扩展gcd求解出y1,回带解得特解(x*) 所以通解是满足合并后的同余方程的所有同余类解:x mod (lcm(

利用中国剩余定理(求解一元线性同余方程组)