HDU 1573 X问题 数论(中国剩余定理)

HDU 1573 X问题 数论(中国剩余定理),第1张

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1573

中国剩余定理解的个数

注意是非互质情况下的中国剩余定理

N===a1(mod r1)

N===a2(mod r2)

以两个为例,则N=a1+r1*x=a2+r2*y,根据后两者就可以建立方程  r1*x-r2*y=a2-a1,扩展欧几里德可搞。

解出x之后 可知N=a1+r1*x,明显这是其中一组解,N+K*(r1*r2)/gcd都是解。


代码如下:

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;

/*
freopen("input.txt",  "r", stdin);  //读数据
freopen("output.txt", "w", stdout); //注释掉此句则输出到控制台
*/
int n,m,b[15],w[15];
//扩展Euclid求解gcd(a,b)=ax+by
int ext_gcd(int a,int b,int& x,int& y)
{
    int t,ret;
    if (!b)
    {
        x=1,y=0;
        return a;
    }
    ret=ext_gcd(b,a%b,x,y);
    t=x,x=y,y=t-a/b*y;
    return ret;
}

void China_left()
{
    int flag,w1,w2,b1,b2,gcd,x,y,i,t;
    flag=0;w1=w[0];b1=b[0];
    for(i=1;i<m;i++)
    {
        w2=w[i];b2=b[i];
        gcd=ext_gcd(w1,w2,x,y);
        if((b2-b1)%gcd)
        {
            flag=1;break;
        }
        t=w2/gcd;
        x=(x*(b2-b1))/gcd;
        x=(x%t+t)%t;
        b1=w1*x+b1;
        w1=(w1*w2)/gcd;
        b1=(b1%w1+w1)%w1;
    }
    if(flag||n<b1)
        printf("0\n");
    else
        printf("%d\n",(n-b1)/w1+1-(b1==0?1:0));
}

int main()
{
    int i,j,k,tt;
    cin>>tt;
    while(tt--)
    {
        cin>>n>>m;
        for(i=0;i<m;i++)
            scanf("%d",&w[i]);
        for(i=0;i<m;i++)
            scanf("%d",&b[i]);

        China_left();
    }
    return 0;
}



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/2083174.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-07-22
下一篇 2022-07-22

发表评论

登录后才能评论

评论列表(0条)

保存