zoukankan      html  css  js  c++  java
  • EXCRT(扩展中国剩余定理)

    (excrt) ( ext{是用来解决当模数不互质的情况下的普通}crt ext{情况的})

    具体见P4777

    事实上和(crt)没有什么关系

    主要思想是:我们不断的合并两个同余方程,最后合并到只剩一个。

    对于方程组

    (egin{cases} x equiv b_1 ({ m mod} a_1) \ xequiv b_2 ({ m mod} a_2) \ end{cases})

    我们考虑合并 这两个同余方程组

    我们化为

    (egin{cases} x =a_1k_1+b_1\ x=a_2k_2+b_2 \ end{cases})

    ( herefore a_1k_1+b_1=a_2k_2+b_2)

    ( herefore a_1k_1-a_2k_2=b_2-b_1)

    这个可以用(exgcd)求出一组当(a_1k_1-a_2k_2=(a1,a2))时的特解

    我们将(x/gcd(a1,a2)*(b_2-b_1))就可以得到原方程的一组解

    那么我们可以回代解出(a_1,b_1,a_2,b_2)

    然后

    我们将(b_2-b_1)作为新的(x),([a_1,a_2])作为新的模数,(a_1k_1-a_2k_2)作为新的余数

    我们就成功的合并了两个方程

    然后不停的合并下去,最后的(x)就是答案了

    代码

    /*
    @Date    : 2018-10-07 11:01:36
    @Author  : Adscn (1349957827@qq.com)
    @Link    : https://www.cnblogs.com/LLCSBlog
    */
    #ifdef FASTER
    #pragma GCC diagnostic error "-std=c++11"
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    #pragma GCC optimize("-fgcse")
    #pragma GCC optimize("-fgcse-lm")
    #pragma GCC optimize("-fipa-sra")
    #pragma GCC optimize("-ftree-pre")
    #pragma GCC optimize("-ftree-vrp")
    #pragma GCC optimize("-fpeephole2")
    #pragma GCC optimize("-ffast-math")
    #pragma GCC optimize("-fsched-spec")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC optimize("-falign-jumps")
    #pragma GCC optimize("-falign-loops")
    #pragma GCC optimize("-falign-labels")
    #pragma GCC optimize("-fdevirtualize")
    #pragma GCC optimize("-fcaller-saves")
    #pragma GCC optimize("-fcrossjumping")
    #pragma GCC optimize("-fthread-jumps")
    #pragma GCC optimize("-funroll-loops")
    #pragma GCC optimize("-fwhole-program")
    #pragma GCC optimize("-freorder-blocks")
    #pragma GCC optimize("-fschedule-insns")
    #pragma GCC optimize("inline-functions")
    #pragma GCC optimize("-ftree-tail-merge")
    #pragma GCC optimize("-fschedule-insns2")
    #pragma GCC optimize("-fstrict-aliasing")
    #pragma GCC optimize("-fstrict-overflow")
    #pragma GCC optimize("-falign-functions")
    #pragma GCC optimize("-fcse-skip-blocks")
    #pragma GCC optimize("-fcse-follow-jumps")
    #pragma GCC optimize("-fsched-interblock")
    #pragma GCC optimize("-fpartial-inlining")
    #pragma GCC optimize("no-stack-protector")
    #pragma GCC optimize("-freorder-functions")
    #pragma GCC optimize("-findirect-inlining")
    #pragma GCC optimize("-fhoist-adjacent-loads")
    #pragma GCC optimize("-frerun-cse-after-loop")
    #pragma GCC optimize("inline-small-functions")
    #pragma GCC optimize("-finline-small-functions")
    #pragma GCC optimize("-ftree-switch-conversion")
    #pragma GCC optimize("-foptimize-sibling-calls")
    #pragma GCC optimize("-fexpensive-optimizations")
    #pragma GCC optimize("-funsafe-loop-optimizations")
    #pragma GCC optimize("inline-functions-called-once")
    #pragma GCC optimize("-fdelete-null-pointer-checks")
    #endif
    #include<bits/stdc++.h>
    using namespace std;
    #define IL inline
    #define RG register
    #define gi getint()
    #define gc getchar()
    #define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    typedef long long ll;
    IL ll getint()
    {
        RG ll xi=0;
        RG char ch=gc;
        bool f=0;
        while(ch<'0'|ch>'9')ch=='-'?f=1:f,ch=gc;
        while(ch>='0'&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
        return f?-xi:xi;
    }
    inline ll exgcd(ll a,ll b,ll &x,ll &y){
    	if(!b){
    		x=1,y=0;
    		return a;
    	}
    	ll gcd=exgcd(b,a%b,y,x);
    	y-=(a/b)*x;
    	return gcd;
    }
    struct node{
    	ll mod,a;
    }last,now;
    istream& operator >> (istream&is,node &p)
    {
    	cin>>p.mod>>p.a;
    	return is;
    }
    node join(node p,node q)
    {
    	ll x,y;
    	ll gcd=exgcd(p.mod,q.mod,x,y);
    	x=(x*(__int128)(q.a-p.a)/gcd)%(q.mod/gcd);
    	if((q.a-p.a)%gcd)exit(1);
    	p.a=x*p.mod+p.a;
    	p.mod=p.mod/gcd*q.mod;
    	p.a=(p.a%p.mod+p.mod)%p.mod;
    	return p;
    }
    int main(void)
    {
        #ifdef ONLINE_JUDGE
    //    File("");
        #endif
        ll n;
        cin>>n>>last;
        for(int i=2;i<=n;i++)
        {
        	cin>>now;
        	last=join(last,now);
        }
        cout<<last.a;
        return 0;
    }
    
  • 相关阅读:
    Windows系统结构
    Windows系统基本概念
    基本NT式驱动代码结构
    数据切割
    虚函数
    基类和派生类:谈继承
    jQuery简单的上拉加载
    检测是否为数组
    倒计时案例分析
    获得总的毫秒数
  • 原文地址:https://www.cnblogs.com/LLCSBlog/p/10202361.html
Copyright © 2011-2022 走看看