题目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 中国剩余定理(非互质)
题面数据来自宋逸群
题解
要保证
,显然
然后
,即
即
这就转化为了中国剩余定理
求出y之后,只需验证
即可
摘自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;
}