hdu_1573 X问题(中国剩余定理非互质)

来源:互联网 发布:意大利java自行车 编辑:程序博客网 时间:2024/05/12 20:55

X问题

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5699 Accepted Submission(s): 1950


Problem Description
求在小于等于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)。

Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素。接下来两行,每行各有M个正整数,分别为a和b中的元素。

Output
对应每一组输入,在独立一行中输出一个正整数,表示满足条件的X的个数。

Sample Input
310 31 2 30 1 2100 73 4 5 6 7 8 91 2 3 4 5 6 710000 101 2 3 4 5 6 7 8 9 100 1 2 3 4 5 6 7 8 9

Sample Output
103

中国剩余定理解模线性方程组x = a[i](mod m[i])。
不过因为模不一定互质,可以用合并方程法,解释可以看这里。


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 12#define mod 1000000007#define PI acos(-1.0)#define LL long longusing namespace std;//求整数x和y,使得a*x+b*y=d,且|x|+|y|最小void gcd(LL a, LL b, LL& d, LL& x, LL& y){    if(!b) { d = a; x = 1; y = 0; }    else{ gcd(b, a%b, d, y, x); y -= x*(a/b); }}LL a[maxn], m[maxn];//中国剩余定理不互质 x = a[i](mod m[i])//返回x的最小正整数解,引用参数d为所有mi的最小公倍数LL china(int n, LL *a, LL *m, LL &d){    LL a1 = a[0], m1 = m[0], a2, m2, k1, k2;    for(int i = 1; i < n; i++)    {        a2 = a[i], m2 = m[i];        gcd(m1, m2, d, k1, k2);        if((a2-a1)%d) return 0; //无解        k1 *= (a2-a1)/d;        k2 = m2/d;        k1 = (k1%k2 + k2)%k2;        a1 = k1*m1+a1;        m1 = m1/d*m2;    }    d = m1;    if(!a1) return m1;    else return (a1%m1+m1)%m1;}LL N;int M;int main(){    int T;    scanf("%d", &T);    while(T--)    {        scanf("%lld%d", &N, &M);        for(int i = 0; i < M; i++) scanf("%lld", &m[i]);        for(int i = 0; i < M; i++) scanf("%lld", &a[i]);        LL d;        LL x = china(M, a, m, d);        if(!x || x > N) printf("0\n");        else printf("%lld\n", (N-x)/d+1);    }    return 0;}




0 0
原创粉丝点击