• 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;
    }
    
  • 相关阅读:
    在ireport中使用checkbox
    OpenCV-Python教程(9、使用霍夫变换检测直线)
    编程挑战(6)
    [置顶] Guava学习之Immutable集合
    mongodb在PHP下的应用学习笔记
    通过Camera进行拍照
    无法删除 C_PAN.GHO: 访问被拒绝 解决办法
    使用POI生成Excel报表
    debian下使用siege进行压力测试
    jodd-servlet工具集锦
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/12714615.html
Copyright © 2020-2023  润新知