• 猜数字


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

    中国剩余定理,要注意对a[i]为负数时的处理

    还要注意快速乘法,因为可能溢出导致答案错误

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    ll k,a[17],b[17];
    ll exgcd(ll a,ll b,ll &x,ll &y){
      if(b==0){
        x=1;y=0;return a;
      }
      else{
        ll d=exgcd(b,a%b,y,x);
        y-=(a/b)*x;
        return d;
      }
    }
    ll qmul(ll a,ll b,ll mod){
      ll ret=0;
      for(;b;b>>=1,a=(a+a)%mod){
        if(b&1) ret+=a;
      } 
      return ret;
    } 
    ll lmes(){
      ll tmp=1,m,mf,y,ret=0;;
      for(ll i=1;i<=k;i++) tmp*=b[i];
      for(ll i=1;i<=k;i++){
        m=tmp/b[i];
        ll k=exgcd(m,b[i],mf,y);
        mf=(mf%b[i]+b[i])%b[i];
        ret=(ret+qmul(qmul(a[i],m,tmp),mf,tmp))%tmp;
      }
      return (ret+tmp)%tmp;
    }
    int main(){
      cin>>k;
      for(ll i=1;i<=k;i++) cin>>a[i];
      for(ll i=1;i<=k;i++) cin>>b[i];
      for(ll i=1;i<=k;i++) a[i]=(a[i]%b[i]+b[i])%b[i];
      cout<<lmes()<<endl;
      return 0;
    }
  • 相关阅读:
    [HDU 3038] How Many Answers Are Wrong
    [BZOJ 4977][Lydsy1708月赛]跳伞求生
    [BZOJ4974] 字符串大师
    总结-exCRT
    [luogu 4777] exCRT
    [AHOI 2009] 中国象棋
    JavaScript MVC框架PK:Angular、Backbone、CanJS与Ember
    十一黄金周 加班加点随笔
    从两个设计模式到前端MVC-洪宇
    Todo&Rocket
  • 原文地址:https://www.cnblogs.com/lcan/p/9803696.html
Copyright © 2020-2023  润新知