zoukankan      html  css  js  c++  java
  • P3868 [TJOI2009]猜数字

    传送门

    中国剩余定理模板题(关于中国剩余定理,我是在这里学的:传送门

    由题可知:

      n-ai=k*bi  --->  n-ai ≡ 0 (mod bi)  --->  n≡ai (mod bi)

    直接用中国剩余定理解同余方程组就好了

    注意一些坑点:

    1. ai可能为负

    因为 ai 是在模 bi 意义下的,所以可以很容易地转成正数: ai=(ai%bi+bi)%bi

    2. 相乘过程中会爆 long long

    这时我们要用神奇的O(1)快速乘... 当然你要用龟速乘也可以...

    具体看代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    ll mo=1;
    inline ll ksc(ll x,ll y)//O(1)快速乘
    {
        ll tmp=(x*y-(ll)((long double)x/mo*y+1.0e-8)*mo);
        return tmp<0 ? tmp+mo : tmp;
    }
    void exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(!b) { x=1,y=0; return; }
        exgcd(b,a%b,x,y);
        ll t=x; x=y;
        y=t-a/b*y;
    }
    const int N=107;
    ll a[N],b[N],ans,n,x,y;
    ll China()
    {
        for(int i=1;i<=n;i++) mo*=b[i];
        for(int i=1;i<=n;i++)
        {
            ll m=mo/b[i];
            exgcd(m,b[i],x,y);
            if(x<0) x=(x%b[i]+b[i])%b[i];
            ans=(ans+ksc( ksc(x,a[i]) , m) )%mo;
        }
        if(ans<0) ans=ans+mo;//注意答案的符号
        return ans;
    }
    
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++) cin>>b[i];
        for(int i=1;i<=n;i++) a[i]=(a[i]%b[i]+b[i])%b[i];//注意转成正数
        cout<<China();
        return 0;
    }
  • 相关阅读:
    SSH框架——Sprign声明式事务
    SSH框架的简化
    Spring声明式事务管理
    简化注解shh框架
    ssh 的搭建
    基础篇-spring包的下载
    基础篇-struts2的搭建
    spring声明式事务管理
    shh简化
    shh(struts+spring+Hibernate)的搭建
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9778969.html
Copyright © 2011-2022 走看看