hdu3579(线性同余方程组)

Hello Kiki

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2734    Accepted Submission(s): 1010

Problem Description

One
day I was shopping in the supermarket. There was a cashier counting
coins seriously when a little kid running and singing "门前大桥下游过一群鸭,快来快来
数一数,二四六七八". And then the cashier put the counted coins back morosely and
count again...
Hello Kiki is such a lovely girl that she loves doing
counting in a different way. For example, when she is counting X coins,
she count them N times. Each time she divide the coins into several
same sized groups and write down the group size Mi and the number of the
remaining coins Ai on her note.
One day Kiki‘s father found her note and he wanted to know how much coins Kiki was counting.

Input

The first line is T indicating the number of test cases.
Each
case contains N on the first line, Mi(1 <= i <= N) on the second
line, and corresponding Ai(1 <= i <= N) on the third line.
All numbers in the input and output are integers.
1 <= T <= 100, 1 <= N <= 6, 1 <= Mi <= 50, 0 <= Ai < Mi

Output

For
each case output the least positive integer X which Kiki was counting
in the sample output format. If there is no solution then output -1.

Sample Input

2
2
14 57
5 56
5
19 54 40 24 80
11 2 36 20 76

Sample Output

Case 1: 341
Case 2: 5996

Author

digiter (Special Thanks echo)

Source

2010 ACM-ICPC Multi-University Training Contest(14)——Host by BJTU

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;

/*对于x=r0(mod m0)
     x=r1(mod m1)
        ...
     x=rn(mod mn)
输入数组m和数组r,返回[0,[m0,m1,...,mn]-1] 范围内满足以上等式的x0。
x的所有解为:x0+z*[m0,m1,...mn](z为整数)
*/
long long cal_axb(long long a,long long b,long long mod)
{
    //防乘法溢出
    long long sum=0;
    while(b)
    {
        if(b&1) sum=(sum+a)%mod;
        b>>=1;
        a=(a+a)%mod;
    }
    return sum;
}

//ax + by = gcd(a,b)
//传入固定值a,b.放回 d=gcd(a,b), x , y
void extendgcd(long long a,long long b,long long &d,long long &x,long long &y)
{
    if(b==0){d=a;x=1;y=0;return;}
    extendgcd(b,a%b,d,y,x);
    y -= x*(a/b);
}

long long Multi_ModX(long long m[],long long r[],int n,long long &M)
{
    long long m0,r0;
    m0=m[0]; r0=r[0];
    for(int i=1;i<n;i++)
    {
        long long m1=m[i],r1=r[i];
        long long k0,k1;
        long long tmpd;
        extendgcd(m0,m1,tmpd,k0,k1);
        if( (r1 - r0)%tmpd!=0 ) return -1;
        k0 *= (r1-r0)/tmpd;
        m1 *= m0/tmpd;
        r0 = ( cal_axb(k0,m0,m1)+r0)%m1;
        m0=m1;
    }
    M=m0;
    return (r0%m0+m0)%m0;
}

int main()
{
    int T;
    cin>>T;
    int tt=1;
    while(T--)
    {
        int n;
        cin>>n;
        long long a[10],b[10];
        for(int i=0;i<n;i++)
             cin>>a[i];
        for(int i=0;i<n;i++)
            cin>>b[i];
        long long M;
        long long ans=Multi_ModX(a,b,n,M);
        printf("Case %d: ",tt++);
        if(ans==0) ans+=M;
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-12-14 06:29:02

hdu3579(线性同余方程组)的相关文章

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&

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

解法:直接上模版. 扩展欧几里德的模版: 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=

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>

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的正整数,则

poj3708(公式化简+大数进制装换+线性同余方程组)

刚看到这个题目,有点被吓到,毕竟自己这么弱. 分析了很久,然后发现m,k都可以唯一的用d进制表示.也就是用一个ai,和很多个bi唯一构成. 这点就是解题的关键了. 之后可以发现每次调用函数f(x),相当于a(ai),b(bi)了一下.这样根据置换的一定知识,一定会出现循环,而把循环的大小看成取模,把从m->k的看成余,于是可以建立一个线性同余方程. 直接用模板解决之.. Recurrent Function Time Limit: 1000MS   Memory Limit: 65536K To

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

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

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

poj2891(线性同余方程组)

一个exgcd解决一个线性同余问题,多个exgcd解决线性同余方程组. Strange Way to Express Integers Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 12001   Accepted: 3797 Description Elina is reading a book written by Rujia Liu, which introduces a strange way to expre