• CodeForces-338D GCD Table


    题目描述

    一张(n imes m) 的表,第$i (行第)j 列$是。

    (GCD(i,j))你有一个长度为(k) 的数列(A),询问是否存在(i,j)

    满足对任意的(l),均有(GCD(i,j+l-1)=a_l(1leq lleq k))

    Input

    第一行有(3)个整数(n,m,k)

    第二行有(k)个整数表示数组(A)

    $ 1<=n,m<=10^{12}1<=k<=10000 $

    $ 1<=a_{i}<=10^{12}$

    Output

    若存在输出(YES),否则输出(NO)

    Sample Input

    100 100 5
    5 2 1 2 1
    
    100 8 5
    5 2 1 2 1
    
    100 100 7
    1 2 3 4 5 6 7
    

    Sample Output

    YES
    
    NO
    
    NO
    

    题目中要求我们在表中找到数列(A)

    即:

    [egin{cases} GCD(i,j)=A_1 \ GCD(i,j+1)=A_2 \ ...... \ GCD(i,j+k-1)=A_k\ end{cases} ]

    由于(GCD)内外可以同时除掉一个数,所以我们同时除掉(A_i)

    有:

    [egin{cases} GCD(i/A_1,j/A_1)=1 \ GCD(i/A_2,(j+1)/A_2)=1 \ ...... \ GCD(i/A_k,(j+k-1)/A_k)=1\ end{cases} ]

    题目开始变得明朗了起来。

    首先,我们发现(i)必定能整除所有的(A_i),即(i)一定是(LCM(A))的倍数。

    同时,我们又发现(j/A_1)为整数,((j+1)/A_2)为整数,即:

    [egin{cases} j=0\%A_1 \ j+1=0\%A_2 \ ...... \ j+k-1=0\%A_k\ end{cases} ]

    我们可以利用中国剩余定理解出(j)的解集。

    我们发现(j)的解集一定是(Ans+k*LCM(A))

    让我们再回到之前的解题中去。

    (i=t*LCM(A),j=Ans+k*LCM(A))

    让我们证明(i)(LCM(A))时最优:


    (j)的解集和(i)并没有关系.

    在上面的条件中,我们要求(GCD(t*(LCM(A)/A_i),(j+i-1)/A_i)=1).

    我们发现若(t)不等于(1)时,在(GCD)中必定会多带入一个因子,这样的话会使(GCD)(1)变的比较麻烦。

    所以,我们取(i=LCM(A))一定是最优的。


    即然(i)已经取了(LCM(A)),那(j)自然是取(Ans)了,否则的话由会多了(LCM(A))的项。

    最后带入检验即可。

    一个坑点:两个数相乘会炸long long,要用快速乘。

    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define int long long
    #define reg register
    #define clr(a,b) memset(a,b,sizeof a)
    #define Mod(x) (x>=mod)&&(x-=mod)
    #define abs(a) ((a)<0?-(a):(a))
    #define debug(x) cerr<<#x<<"="<<x<<endl;
    #define debug2(x,y) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl;
    #define debug3(x,y,z) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl;
    #define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
    #define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
    #define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
    #define erep(i,G,x) for(int i=(G).Head[x]; i; i=(G).Nxt[i])
    #pragma GCC optimize(2)
     
    inline int Read(void) {
    	int res=0,f=1;
    	char c;
    	while(c=getchar(),c<48||c>57)if(c=='-')f=0;
    	do res=(res<<3)+(res<<1)+(c^48);
    	while(c=getchar(),c>=48&&c<=57);
    	return f?res:-res;
    }
     
    template<class T>inline bool Min(T &a, T const&b) {
    	return a>b?a=b,1:0;
    }
    template<class T>inline bool Max(T &a, T const&b) {
    	return a<b?a=b,1:0;
    }
    const int N=1e4+5,M=305,mod1=97,mod2=3761599;
     
    bool MOP1;
     
    int n,k,m,mod[N],res[N];
     
    bool MOP2;
     
    int Exgcd(int a, int b, int &x, int &y) {
    	if(!b) {
    		x=1,y=0;
    		return a;
    	}
    	int g=Exgcd(b,a%b,y,x);
    	y-=a/b*x;
    	return g;
    }
     
    inline int Mul(int x,int y,int mod) {
    	int res=0,f=0;
    	if(y<0)f=1,y=-y;
    	while(y) {
    		if(y&1)res=(res+x)%mod;
    		x=x+x%mod,y>>=1;
    	}
    	return f?-res:res;
    }
     
    inline int Excrt(void) {
    	int M=mod[1],ans=res[1],x,y;
    	rep(i,2,k) {
    		int g=Exgcd(M,mod[i],x,y);
    		if((res[i]-ans)%g)return -1;
    		y=mod[i]/g;
    		x=Mul(x,(res[i]-ans)/g,y);
    		x=(x+y)%y;
    		ans=M*x+ans,M=M/g*mod[i],ans%=M;
    	}
    	int z=(ans%M+M)%M;
    	if(!z)z=M;
    	return z;
    }
     
    int vis[1000005];
     
    inline void _main(void) {
    	n=Read(),m=Read(),k=Read();
    	rep(i,1,k)mod[i]=Read(),res[i]=((1-i)%mod[i]+mod[i])%mod[i];
    	int LCM=1;
    	rep(i,1,k) {
    		LCM=LCM/__gcd(LCM,mod[i])*mod[i];
    		if(LCM<0||LCM>n)return(void)puts("NO");
    	}
    	int Now=Excrt();
    	if(Now==-1)return(void)puts("NO");
    	if(Now+k-1>m)return(void)puts("NO");
    	rep(i,1,k)if(__gcd(Now+i-1,LCM)!=mod[i])return(void)puts("NO");
    	return(void)puts("YES");
    }
     
    signed main() {
    	_main();
    	return 0;
    }
    
  • 相关阅读:
    【leetcode】1562. Find Latest Group of Size M
    【leetcode】1561. Maximum Number of Coins You Can Get
    【leetcode】1560. Most Visited Sector in a Circular Track
    Python中用format函数格式化字符串的用法
    机器学习最常用优化之一——梯度下降优化算法综述
    python学习之argparse模块
    Ubuntu14.04安装NVIDIA显卡驱动
    Anaconda使用教程
    TensorFlow0.8代码目录结构讲解
    cmake编译opencv程序
  • 原文地址:https://www.cnblogs.com/dsjkafdsaf/p/11577373.html
Copyright © 2020-2023  润新知