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

    首先观察式子(forall i in [1,k])(b_i|(n-a_i))

    可以得出(n-a_i=kb_i)

    (n-a_iequiv0(mod b_i))

    (n equiv a_i (mob b_i))

    这个式子是不是很眼熟??

    没错就是中国剩余定理

    (egin{cases}n equiv a_1 (mob b_1)\n equiv a_2 (mob b_2)\n equiv a_3 (mob b_3)\……\n equiv a_i (mob b_i)end{cases})

    然后就变得简单了,由中国剩余定理的知识可知

    (m=prodlimits_{i=1}^{n}b_i)(M_i=m/b_i)(t_i)是线性同余方程(M_it_iequiv1(mod m_i))的一个解

    解为(x=sumlimits_{i=1}^{n}a_iM_it_i)

    记得用龟速乘

    注:上面的中国剩余定理必须在模数两两互质的情况下,如果不互质,请看扩展中国剩余定理

    /*
    @ author:pyyyyyy
    -----思路------
    -----debug-------
    */
    #include<bits/stdc++.h>
    #define int long long 
    using namespace std;
    const int N=2020;
    int n;
    int a[N],b[N];
    int m=1,M[N],t[N];
    void exgcd(int a,int b,int &x,int &y)
    {
    	if(!b)
    	{
    		x=1;y=0;
    		return ;
    	}
    	exgcd(b,a%b,x,y);
    	int z=x;
    	x=y;y=(z-y*(a/b));
    	return ;
    }
    int mul(int x,int y,int mod)
    {
    	int ret=0;
    	while(y)
    	{
    		if(y&1) ret=(ret+x)%mod;
    		x=(x+x)%mod;
    		y>>=1;
    	}
    	return ret;
    }
    int ans;
    signed main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	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) m*=b[i];
    	for(int i=1;i<=n;++i) M[i]=m/b[i];
    	for(int i=1;i<=n;++i)
    	{
    		int x,y;
    		exgcd(M[i],b[i],x,y);
    		x=(x%b[i]+b[i])%b[i];
    		ans+=mul(a[i],mul(M[i],x,m),m);
    		ans%=m;	
    	}
    	cout<<ans;
    	
    	return 0;
    }
    
  • 相关阅读:
    angularJS解决数据显示闪一下的问题?-解决办法
    js 做账单处理
    淘宝cnpm
    js 对象转数组
    js 移动端上拉刷新(基于ng1)
    js 控制超出字数显示省略号
    select2 插件编辑时设置默认值
    select2 插件加载后端数据
    js 依据“;”折行
    css 两段对齐和超出部分...
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/12714615.html
Copyright © 2011-2022 走看看