CF#338D GCD Table 中国剩余定理(非互质) 数学专题第三题

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/86531681

题目P2102

http://codeforces.com/problemset/problem/338/D
洛谷地址传送门

背景 Background
此系列问题为数论专题
具体参考博文
http://blog.csdn.net/chty2018/article/details/53432272
描述 Description
有一张N*M的表格,i行j列的元素是gcd(i,j)
读入一个长度为k,元素大小不超过10^12的序列a[1…k],问这个序列是否在表格的某一行中出现过
输入格式 Input Format
第一行3个整数,n,m,k
第二行k个整数,第i个整数表示ai
输出格式 Output Format
如果出现过,输出“YES”,否则,输出“NO”
样例输入 Sample Input
100 100 5
5 2 1 2 1
///////////////////////////////////////////////////////////////////////////////
100 8 5
5 2 1 2 1
样例输出 Sample Output
YES
//////////////////////////////////////////////////////////////////////////////
NO
时间限制 Time Limitation
1s
注释 Hint
1<=N,M<=10^12
1<=k<=10^4
来源 Source
【CF#338D】GCD Table 中国剩余定理(非互质)
题面数据来自宋逸群

题解

要保证 g c d ( x , y ) = a [ i ] gcd(x,y)=a[i] ,显然 x = l c m ( a [ 1 ] , a [ 2 ] a [ k ] ) x=lcm(a[1],a[2]……a[k])
然后 y   m o d   a [ 1 ] = 0 y\text{ }mod\text{ }a[1]=0 ,即
( y + i 1 )   m o d   a [ i ] = 0 (y+i-1)\text{ }mod\text{ }a[i]=0
y   m o d   a [ 1 ] = 0 y\text{ }mod\text{ }a[1]=0
y   m o d   a [ 2 ] = 1 y\text{ }mod\text{ }a[2]=-1
……
y   m o d   a [ n ] = ( n 1 ) y\text{ }mod\text{ }a[n]=-(n-1)
这就转化为了中国剩余定理
求出y之后,只需验证 g c d ( x , y + i 1 ) = a [ i ] gcd(x,y+i-1)=a[i] 即可
摘自chty

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
template<typename T>inline void read(T &x)
{
	x=0;
	static ll f=1;
	static char ch=getchar();
	while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
inline ll gcd(ll a,ll b)
{
	return b?gcd(b,a%b):a;
}
inline void exgcd(ll a,ll b,ll &g,ll &x,ll &y)
{
	if (!b)
	{
		x=1,y=0,g=a;
		return ;
	}
	exgcd(b,a%b,g,x,y);
	ll tmp=x;
	x=y;
	y=tmp-a/b*y;
}
ll n,p,k,lcm(1);
ll m[maxn],a[maxn];
inline ll China()
{
    for (int i=1;i<=k;++i)
    	a[i]=1-i;
    ll A=a[1],M=m[1];
    for (int i=2;i<=k;++i)
    {
        ll x,y,data=a[i]-A,g;
		exgcd(M,m[i],g,x,y);
        if (data%g)
			return -1;
        ll tmp=m[i]/g;
        x*=data/g;
        x=(x%tmp+tmp)%tmp;
        A+=x*M;
        M=M*m[i]/g;
        A=(A+M)%M;
    }
    return A;
}
inline bool check()
{
	if (lcm>n) return 0;
	ll ans=China();
	if (ans<0) return 0;
	if (ans==0) ans=lcm;
	if (ans+k-1>p)  return 0;
	for (int i=1;i<=k;++i)
		if (gcd(lcm,ans+i-1)!=m[i])
			return 0;
	return 1;
}
int main()
{
	read(n);read(p);read(k);
	for (int i=1;i<=k;++i)
		read(m[i]);
	for (int i=1;i<=k;++i)
	{
		lcm=lcm/gcd(lcm,m[i])*m[i];
		if (lcm>n)	break;
	}
	if (check())
		puts("YES");
	else
		puts("NO");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/86531681