zoukankan      html  css  js  c++  java
  • 屠龙勇士

    前置知识

    平衡树(或者multiset<long long>)

    扩展中国剩余定理

    扩展欧几里得

    开始

    我们对于每一条龙,都要杀,并且全部按顺序杀

    所以对于一条龙用的剑可以O(nlogn)平衡树搞出来(STL不香??)

    那么我们便可以列举出一堆方程组

    [egin{cases} A_1xequiv a_1pmod{m_1} \ A_2xequiv a_2pmod{m_2} \ dots \ A_nxequiv a_npmod{m_n} end{cases} ]

    是不是有点似曾相识?

    这就是扩展中国剩余定理!!!

    但是他带了系数,咋办?

    我们得把左边(A_i)弄无

    那么

    [ecause A_ixequiv a_ipmod{m_n} \ herefore A_ix=a_i-m_nk \ herefore A_ix+m_nk=a_i ]

    这就是扩展欧拉定理模板呗

    如果无解输出-1

    我们搞出(x,k)的值

    定义

    [egin{cases} lcm_1=m_1 \ lcm_i=lcm(lcm_{i-1},m_i) end{cases} ]

    很显然
    (x)可以加上或减去任意(lcm_{i-1})

    于是有了(xequiv x_0+k'lcm_{i-1},k'in Z)

    (xequiv x_0 pmod{lcm_{i-1}})

    于是就可以扩展中国剩余定理搞出来了

    贴上代码

    #include<bits/stdc++.h>
    #define N 100011
    #define ll long long
    using namespace std;
    multiset<ll>q;
    int n,m;
    inline ll mul(ll a,ll b,ll mod){
    	if(b<0)a=-a,b=-b;
    	ll ans(0);
    	while(!!b){
    		if(b&1)ans=(ans+a)%mod;
    		a=(a<<1)%mod;
    		b>>=1;
    	}
    	return (ans%mod+mod)%mod;
    }
    inline void exgcd(ll a,ll b,ll &x,ll &y,ll &d){
    	if(!b){d=a;x=1;y=0;return;}
    	exgcd(b,a%b,y,x,d);
    	y-=a/b*x;
    }
    ll a[N],p[N],c[N];
    inline void init( ){
    	q.clear( );
    	scanf("%d%d",&n,&m);
    	int i;
    	int op(0);
    	ll g;
    	for(i=1;i<=n;++i)
    	scanf("%lld",&a[i]);
    	for(i=1;i<=n;++i)scanf("%lld",&p[i]);
    	for(i=1;i<=n;++i)
    	scanf("%lld",&c[i]);
    	while(m--){scanf("%lld",&g);q.insert(g);}
    }
    inline multiset<ll>::iterator find(ll k){
    	multiset<ll>::iterator op;
    	op=q.upper_bound(k);
    	if(op!=q.begin( ))--op;
    	return op;
    }
    inline ll gcd(ll a,ll b){
    	return !b?a:gcd(b,a%b);
    }
    inline ll ceil(ll a,ll b){
    	return (a+b-1)/b;
    }
    inline ll maxx(ll a,ll b){
    	return a>b?a:b;
    }
    ll X,lcm;
    inline void work( ){
    	init( );
    	int i;
    	multiset<ll>::iterator k;
    	ll x,y,d,QWQ(0);
    	ll P,A;
    	for(i=1;i<=n;++i){
    		k=find(a[i]);
    		exgcd(*k,p[i],x,y,d);
    		if(a[i]%d!=0){puts("-1");return;}
    		QWQ=maxx(QWQ,ceil(a[i],*k));
    		A=mul(x,a[i]/d,p[i]/d);
    		P=p[i]/d;
    		if(i==1){
    			lcm=P;
    			X=A;
    		}else{
    			exgcd(lcm,P,x,y,d);
    			if((A-X)%d!=0){puts("-1");return;}
    			x=mul((A-X)/d,x,P/d);
    			ll qwq(lcm);
    			lcm=lcm/d*P;
    			X=(X+(mul(x,qwq,lcm)%lcm+lcm)%lcm)%lcm;
    		}
    		q.erase(k);
    		q.insert(c[i]);
    	}
    	if(!X)X=QWQ;
    	printf("%lld
    ",X);
    }
    int main( ){
    	int t;
    //	freopen("dragon2.in","r",stdin);
    //	freopen("ans.out","w",stdout);
    	scanf("%d",&t);
    	while(t--)work( );
    } 
    
  • 相关阅读:
    使用WCF实现SOA面向服务编程—— 架构设计
    ASP.NET MVC 4 RC的JS/CSS打包压缩功能
    自定义WCF的配置文件
    C#综合揭秘——分部类和分部方法
    结合领域驱动设计的SOA分布式软件架构
    【转】数字证书类型
    kubeadm部署单master Kuberntes集群
    持续交付
    编译在docker alpine中可用的go程序
    百度云盘,文件重命名
  • 原文地址:https://www.cnblogs.com/the-Blog-of-Mikasa/p/13771597.html
Copyright © 2011-2022 走看看