HDU 1573 模线性方程

给定模线性方程组,求最终的值的通解。点击

两个模方程可以化解成一个模方程

x mod a1 = b1

x mod a2 = b2

a1*k1 + a2*k2 = b2 – b1 // 其中k1k2是自由元

用扩展欧几里得算出k1的解,当然它是一个解系,找出最小k1作为特解,带入x = a1 * k1 + b1得到x

然后把这个x当作特解,记作x1.

之前k1本来是一个解系,他的模是a2/gcd(a1,a2),[简单将gcd(a1,a2)记作t], 也就是说k1如果作为一个解系的话,k1 = a2/t * x + k0

其中x是任意整数,k0是一个特解。

将求到的k1代入到x = a1 * k1 + b1 中,得到的是一个x的解系,如果用上边的特解x0表示,就是x = x0 + a1*a2/t;

得到一个新的模方程 x mod a1*a2/t = x0 ,这个方程继承上面两个方程的特性,所以两者之间是等价的。

这样将两个两个方程消掉,最后只剩下一个方程,最后的解系就是最终的x的解系。如果中间出现欧几里得算不出来解,那么说明这个方程组没有解。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1e6 + 500;

void extend_gcd(LL a, LL b, LL &x, LL &y, LL &d)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        d = a;
    }
    else
    {
        extend_gcd(b, a%b, y, x, d);
        y -= (a/b) * x;
    }
}
int T,n,m;
LL a[20],b[20];

int main()
{
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < m; i++)
            scanf("%d", &a[i]);
        for(int j = 0; j < m; j++)
            scanf("%d", &b[j]);

        LL flag = 0;
        LL x, y, d;
        LL m1 = a[0], r1 = b[0];
        LL m2, r2;
        LL c, t;
        for(int i = 1; i < m; i++)
        {
            m2 = a[i], r2 = b[i];
            extend_gcd(m1, m2, x, y, d);//d = gcd(m1,m2)  m1*x + m2*y = gcd(m1,m2)
            c = r2 - r1;
            if(c % d)
            {
                flag = 1;
                break;
            }

            t = m2 / d; // m1*(x+m2/d*k1) + m2*(y + m1/d*k2) = m1*x + m2*y + (m1*m2/d * k1 + m2*m1/d*k2) = gcd(m1,m2)
            x = (((x * c / d) % t) + t) % t;

            r1 = m1*x + r1;
            m1 = m1*m2/d;
            r1 %= m1;
        }
        int ans = 0;
        if(flag || r1 > n)
        {
            printf("0\n");
        }
        else
        {
            int ans = (n - r1) / m1 + 1;
            if(r1 == 0) ans--;
            printf("%d\n", ans);
        }

    }

    return 0;

}
时间: 2024-10-11 06:23:26

HDU 1573 模线性方程的相关文章

POJ 2115 C Looooops(模线性方程)

http://poj.org/problem?id=2115 题意: 给你一个变量,变量初始值a,终止值b,每循环一遍加c,问一共循环几遍终止,结果mod2^k.如果无法终止则输出FOREVER. 思路: 根据题意原题可化成c * x = b - a mod (2 ^ k),然后解这个模线性方程. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio>

POJ 2115 (模线性方程 -&gt; 扩展欧几里得)

题意: for(i=A ; i!=B ;i +=C)循环语句,问在k位操作系统中循环结束次数. 若在有则输出循环次数. 否则输出死循环. 存在这样的情况:i= 65533 :i<=2:i+= 4:时i = 2: 由模线性方程->扩展欧几里得 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using

HDU 1573 CRT

CRT模板题 /** @Date : 2017-09-15 13:52:21 * @FileName: HDU 1573 CRT EXGCD.cpp * @Platform: Windows * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair

POJ2115——C Looooops(扩展欧几里德+求解模线性方程)

C Looooops DescriptionA Compiler Mystery: We are given a C-language style for loop of type for (variable = A; variable != B; variable += C) statement;I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repea

HDU 1573 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). 思路:中国剩余定理的模板题,如果找不到这样的数或者最小的X大于N,输出零. 代码: #include <iostream> #include

模线性方程 poj2115

1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 long long exgcd(long long a,long long b,long long &x,long long &y) 7 { 8 if(b==0) 9 { 10 x=1; 11 y=0; 12 return a; 13 } 14 long long ret=exgcd(b,a%b,x,y); 15 long l

POJ 2115 模线性方程 ax=b(mod n)

/* (x*c+a)%(2^k)==b →(x*c)%(2^k)==b-a 满足定理: 推论1:方程ax=b(mod n)对于未知量x有解,当且仅当gcd(a,n) | b. 推论2:方程ax=b(mod n)或者对模n有d个不同的解,其中d=gcd(a,n),或者无解. 定理1:设d=gcd(a,n),假定对整数x和y满足d=ax+by(比如用扩展Euclid算法求出的一组解). 如果d | b,则方程ax=b(mod n)有一个解x0满足x0=x*(b/d) mod n .特别的设e=x0+

中国剩余定理 hdu 1573 X问题

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

poj 2115 (解单变元模线性方程)

http://poj.org/problem?id=2115 题意: 给出a,b,c,k,求x,使得(a+c*x)%(2^k)=b 限制: 0 <= a,b,c < 2^k; 1 <= k <= 32 思路: 拓展欧几里得单变元模线性方程 令 A=c;C=((b-a)%(2^k)+2^k)%(2^k);B=2^k 则这道题就化为Ax%n=B 对于Ax%B=C -> Ax+By=C -> d=Ext_gcd(A,B,x,y) //d其实为gcd(A,B) -> if