zoukankan      html  css  js  c++  java
  • P1495 曹冲养猪

    CRT----中国剩余定理

    题意:给你n个式子$x equiv b_i (mod a_i)$,求x的最小正整数解(CRT裸题)

    中国剩余定理求解

    考虑每一个式子i$left{egin{aligned}x equiv 0 (mod a_1) \ x equiv 0 (mod a_2) \  x equiv 0 (mod a_2)  \ .\.\.\ x  equiv 1 (mod a_i)  \.\.\.\  x equiv 0 (mod a_n)end{aligned} ight.$ 

    可以求出每个式子的解$x_i$,则$ans=sum{x_i*b_i}(mod Pi{a_i})$

    那么,考虑怎么求解每一个式子i

    首先,对于每一个j$x_i equiv 0 (mod a_j)$

    不难得出$x_iequiv 0 (mod Pi{a_j})$

    我们令$N=Pi{a_j}$

    $x_iequiv 0 (mod frac{N}{a_i})$

    也就是说$x_i=k*frac{N}{a_i}$

    而对于那个特殊的式子i$x_i equiv 1 (mod a_i)$

    可以得出$x_i=p*a_i+1$

    因此$x_i=p*a_i+1=k* frac{N}{a_i}$

    $p*a_i+1=k* frac{N}{a_i}$

    $k* frac{N}{a_i}-p*a_i=1$

    有没有get到什么》》??

    显然的exgcd啊

    因此,k与p就得到了

    反推回去,x也得到了

    最后,ans就求出来了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define int long long
    #define olinr return
    #define _ 0
    #define love_nmr 0
    #define DB double
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    int n;
    inline void exgcd(int a,int b,int &x,int &y)
    {
        if(!b)
        {
            x=1;
            y=0;
            return;
        }
        exgcd(b,a%b,x,y);
        int t=x-a/b*y;
        x=y;
        y=t;
    }
    int bb[20];
    int aa[20];
    int ans;
    int N=1;
    inline int work(int pos)
    {
        int p,k;
        exgcd(N/aa[pos],aa[pos],p,k);
        int ansx=p*(N/aa[pos]);
        return (ansx*bb[pos])%N;
    }
    signed main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        {
            aa[i]=read();
            bb[i]=read();
        }
        for(int i=1;i<=n;i++)
            N*=aa[i];
        for(int i=1;i<=n;i++)
            (ans+=work(i))%=N;
        put(ans>0? ans:ans+N);
        olinr ~~(0^_^0)+love_nmr;
    }
  • 相关阅读:
    第二十二节:类与对象后期静态绑定对象和引用
    WePHP的表单令牌验证
    第二十一节:类与对象对象的比较类型约束
    Windows下 C++ 实现匿名管道的读写操作
    Mongoose 利用实现HTTP服务
    C++ Qt 框架静态编译 操作记录
    使用Qt框架开发http服务器问题的记录
    把CMD下的color 方案遍历一遍
    C++学习笔记
    在1~10的整数范围随机5个不重复的整数
  • 原文地址:https://www.cnblogs.com/olinr/p/9614504.html
Copyright © 2011-2022 走看看