HDU 1573 X问题 中国剩余定理

来源:互联网 发布:阿里云服务器支持ipv6 编辑:程序博客网 时间:2024/05/16 00:48

链接: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,输出零。

资料:http://yzmduncan.iteye.com/blog/1323599/

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <map>#include <cstdlib>#include <queue>#include <stack>#include <vector>#include <ctype.h>#include <algorithm>#include <string>#include <set>#define PI acos(-1.0)#define maxn 10005#define INF 0x7fffffff#define eps 1e-8typedef long long LL;typedef unsigned long long ULL;using namespace std;LL MOD;LL extend_gcd(LL a, LL b, LL &x, LL &y){    if(b==0)    {        x=1;        y=0;        return a;    }    LL r=extend_gcd(b,a%b,x,y);    LL t=x;    x=y;    y=t-a/b*y;    return r;}LL inv(LL a,LL m){    LL d,x,y;    d=extend_gcd(a,m,x,y);    if (d==1)    {        x=(x%m+m)%m;        return x;    }    else return -1;}LL gcd(LL a,LL b){    return b==0?a:gcd(b,a%b);}bool merge(LL a1,LL m1,LL a2,LL m2,LL &a3,LL &m3){    LL d=gcd(m1,m2);    LL c=a2-a1;    if(c%d)        return false;    c=(c%m2+m2)%m2;    c/=d;    m1/=d;    m2/=d;    c*=inv(m1,m2);    c%=m2;    c*=m1*d;    c+=a1;    m3=m1*m2*d;    a3=(c%m3+m3)%m3;    return true;}LL CRT_next(LL a[],LL m[],int n){    LL a1=a[0],m1=m[0],a2,m2;    for(int i=1;i<n;i++)    {        LL aa,mm;        a2=a[i],m2=m[i];        if(!merge(a1,m1,a2,m2,aa,mm))            return -1;        a1=aa;        m1=mm;    }    MOD=m1;    LL aa=(a1%m1+m1)%m1;    if(aa==0)    aa+=m1;    return aa;}int main(){    int T;    LL a[55],b[55];    scanf("%d",&T);    for(int ii=1; ii<=T; ii++)    {        int tot;        LL t1;        scanf("%I64d%d",&t1,&tot);        for(int i=0; i<tot; i++)            scanf("%I64d",&a[i]);        for(int i=0; i<tot; i++)            scanf("%I64d",&b[i]);        if(tot==1)        {            if(b[0]==0)                b[0]+=a[0];            if(t1<b[0])                printf("0\n");            else                printf("%I64d\n",(t1-b[0])/a[0]+1);        }        else        {            LL ans=CRT_next(b,a,tot);            if(ans==-1)                printf("0\n");            else if(ans>t1)                printf("0\n");            else                printf("%I64d\n",(t1-ans)/MOD+1);        }    }    return 0;}


0 0
原创粉丝点击