zoukankan      html  css  js  c++  java
  • 中国剩余定理 快速乘 洛谷P3868

    题目链接:https://www.luogu.org/problem/P3868

    题意:就是裸的中国剩余定理,为了防止TLE要加上快速乘,但是要注意a[i]可能为负数,故需要对a[i]做处理:a[i]=(a[i]%b[i]+b[i])%b[i])

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long lt;
    
    lt read()
    {
        lt f=1,x=0;
        char ss=getchar();
        while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
        while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
        return x*f;
    }
    
    int k;
    lt a[20],b[20];
    
    lt qmul(lt a,lt b,lt mod)
    {
        lt ans=0;
        while(b>0)
        {
            if(b&1) ans=(ans+a)%mod;
            a=(a+a)%mod;
            b>>=1;
        }
        return ans;
    }
    
    void exgcd(lt a,lt b,lt &x,lt &y)
    {
        if(b==0){ x=1; y=0; return;}
        exgcd(b,a%b,x,y);
        int tp=x;
        x=y; y=tp-a/b*y;
    }
    
    lt china()
    {
        lt ans=0,lcm=1,x,y;
        for(int i=1;i<=k;++i) lcm*=b[i];
        for(int i=1;i<=k;++i)
        {
            lt tp=lcm/b[i];
            exgcd(tp,b[i],x,y);
            x=(x%b[i]+b[i])%b[i];
            ans=(ans+qmul(qmul(tp,x,lcm),a[i],lcm))%lcm;//记得快速乘
        }
        return (ans+lcm)%lcm;
    }
    
    int main()
    {
        k=read();
        for(int i=1;i<=k;++i) a[i]=read();
        for(int i=1;i<=k;++i) b[i]=read();
        for(int i=1;i<=k;i++) a[i]=(a[i]%b[i]+b[i])%b[i];
        cout<<china();
        return 0;
        //niiick
    }
  • 相关阅读:
    洛谷 1736 创意吃鱼法
    有多重限制的背包
    洛谷 1417 烹调方案
    2008 noip 传纸条
    环形石子合并 洛谷 1880 && hdu 3506 Monkey Party
    洛谷 1282 多米诺骨牌
    (金明的预算方案)依赖性的背包
    分组背包问题
    混合背包问题
    多重背包问题
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/11386843.html
Copyright © 2011-2022 走看看