• [TJOI2009]猜数字(中国剩余定理)


    洛咕

    题意:有两组数字,每组k个,第一组中的数字分别为a1,a2,...,ak,第二组中的数字分别为b1,b2,...,bk.其中第二组中的数字两两互素.求最小的非负整数n,满足对于任意的i,n-ai能被bi整除.

    分析:看懂题目之后,就是裸的中国剩余定理.

    n-ai能被bi整除,即(n-a_i≡0(mod b_i)),移项得(n≡a_i(mod b_i)),然后有k个这样的方程构成方程组,且bi两两互质.裸题证毕.

    几个细节:ai可能为负数,稍微处理一下.然后出题人很毒瘤,最后相乘的时候会爆long long,所以要用快速乘(会快速幂就会快速乘).

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline LL read(){
        LL s=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
        return s*w;
    }
    LL k,M=1,ans;
    LL a[11],b[11];
    LL quickmul(LL a,LL b,LL mod){
        LL ans=0;
        while(b){
            if(b&1)ans=(ans+a)%mod;
            a=(a+a)%mod;
            b>>=1;
        }
        return ans;
    }//快速乘:快速幂的乘号变加号
    LL exgcd(LL a,LL b,LL &x,LL &y){
        if(b==0){x=1;y=0;return a;}
        LL d=exgcd(b,a%b,y,x);
        y-=x*(a/b);
        return d;
    }
    void Intchina(){
        LL Mi,x,y;
        for(int i=1;i<=k;++i){
            Mi=M/b[i];
            exgcd(Mi,b[i],x,y);
            x=(x%b[i]+b[i])%b[i];
            ans=(ans+quickmul(quickmul(Mi,x,M),a[i],M))%M;
        }
        printf("%lld
    ",(ans+M)%M);
    }
    int main(){
        k=read();
        for(int i=1;i<=k;i++){
    		a[i]=read();
        }
        for(int i=1;i<=k;i++){
    		b[i]=read();M*=b[i];
    		while(a[i]<0)a[i]+=b[i];//处理一下ai
        }
        Intchina();
        return 0;
    }
    
    
  • 相关阅读:
    C#设计模式学习笔记-单例模式
    面向对象的七种设计原则
    继承 示例1
    继承和多态的那些事
    体检套餐管理项目
    魔兽登录系统
    清空表
    mysql批量插入
    mkdir用大括号同时建立多个同级和下级目录
    linux查看机器位数
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10502013.html
Copyright © 2020-2023  润新知