一本通1634【例 4】曹冲养猪

曹冲养猪

 

描述

自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。举个例子,假如有16头母猪,如果建了3个猪圈,剩下1头猪就没有地方安家了。如果建造了5个猪圈,但是仍然有1头猪没有地方去,然后如果建造了7个猪圈,还有2头没有地方去。你作为曹总的私人秘书理所当然要将准确的猪数报给曹总,你该怎么办?

格式

输入格式

第一行包含一个整数n (n <= 10) – 建立猪圈的次数,解下来n行,每行两个整数ai, bi( bi <= ai <= 1000), 表示建立了ai个猪圈,有bi头猪没有去处。

//你可以假定ai,aj互质.

输出格式

输出包含一个正整数,即为曹冲至少养母猪的数目。

样例1

样例输入1

3
3 1
5 1
7 2

样例输出1

16

sol:孙子定理,挺容易理解的吧。。。
给你n个数A[i],B[i],求出一个数N满足 ∑ N%A[i]=B[i]
要用到中国剩余定理(孙子定理),首先定义一个Mod=∏A[i]
对于当前一个A[i],定义一个P=Mod/A[i]
因为Ai和Aj两两互质,所以P一定与Ai互质
此时的P%其他Aj都是0,所以可以放心使用
暴力的方法就是一句while
ll Sum=P;
while(Sum%A[i]!=1)
{
    Sum+=P;
}
这肯定会T出屎来,观察式子可得如下的过程

k*P%A[i] = 1
k*P = 1+kk*A[i]
k*P+kk*A[i] = 1 (类似ax+by=c的形式)

同时因为Ai和P互质,gcd=1,而且求通解的公式中的b/gcd变成了b

然后求出Ecgcd中的X后,放心的把ans+=X*P*B[i],因为这个数%其他Aj都是0嘛

还有全部加起来可能会爆long long,需要模一个数,这个数就是前面的 Mod=∏A[i]

因为Mod%所有Ai都为0,这就是为什么我要把变量名叫做Mod的原因了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
ll n;
ll A[15],B[15];
inline void Exgcd(ll a,ll b,ll &X,ll &Y)
{
    if(b==0)
    {
        X=1;
        Y=0;
        return;
    }
    Exgcd(b,a%b,X,Y);
    ll XX=X,YY=Y;
    X=YY;
    Y=XX-a/b*YY;
    return;
}
inline ll gcd(ll x,ll y)
{
    return (!y)?(x):(gcd(y,x%y));
}
int main()
{
    int i;
    ll Mod=1,ans=0;
    R(n);
    for(i=1;i<=n;i++)
    {
        Mod*=(A[i]=read());
        R(B[i]);
    }
    for(i=1;i<=n;i++)
    {
        ll P=Mod/A[i];
        /*
            k*P%A[i] = 1
            k*P = 1+kk*A[i]
            k*P+kk*A[i] = 1 (类似ax+by=c的形式)
        */
        ll a=P,b=A[i],c=1;
        ll X,Y;
        Exgcd(a,b,X=0,Y=0);
        ll tmp=b;
        X=(X>=0)?(X%tmp):(X%tmp+tmp);
        ans=(ans+X*P*B[i]%Mod)%Mod;
    }
    Wl(ans);
    return 0;
}
/*
input
3
3 1
5 1
7 2
output
16

input
2
99982 19823
99983 92834
output
2696734327
*/
View Code

 

posted @ 2019-02-28 22:11  yccdu  阅读(574)  评论(1编辑  收藏  举报