GCD Table
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit
Status
Description
Consider a table G of size n × m such that G(i, j) = GCD(i, j) for all 1 ≤ i ≤ n, 1 ≤ j ≤ m. GCD(a, b) is the greatest common divisor of numbers a and b.
You have a sequence of positive integer numbers a1, a2, …, ak. We say that this sequence occurs in table G if it coincides with consecutive elements in some row, starting from some position. More formally, such numbers 1 ≤ i ≤ n and 1 ≤ j ≤ m - k + 1 should exist that G(i, j + l - 1) = al for all 1 ≤ l ≤ k.
Determine if the sequence a occurs in table G.
Input
The first line contains three space-separated integers n, m and k (1 ≤ n, m ≤ 1012; 1 ≤ k ≤ 10000). The second line contains k space-separated integers a1, a2, …, ak (1 ≤ ai ≤ 1012).
Output
Print a single word “YES”, if the given sequence occurs in table G, otherwise print “NO”.
Sample Input
Input
100 100 5
5 2 1 2 1
Output
YES
Input
100 8 5
5 2 1 2 1
Output
NO
Input
100 100 7
1 2 3 4 5 6 7
Output
NO
Hint
Sample 1. The tenth row of table G starts from sequence {1, 2, 1, 2, 5, 2, 1, 2, 1, 10}. As you can see, elements from fifth to ninth coincide with sequence a.
Sample 2. This time the width of table G equals 8. Sequence a doesn’t occur there.
題意:GCD(i , j + r - 1) = a[r] (k>=r >=1)
思路:
1. J % a[1] = 0
(J + 1) % a[2] = 0
……
(J + k - 1) % a[k] = 0
互质的中国剩余定理[从假设可知,对任何 ,由于 ,所以 这说明存在整数 使得 这样的 叫做 模 的数论倒数。考察乘积 可
满足:
lcm/m[i]*t(inverse)*a[i]
本题
不互质的
#include
#include
#define LL long long
using namespace std;
const int maxn=10005;
LL n,m,a[maxn],b[maxn];
int k;
LL gcd(LL a,LL b)
{
if(!b)return a;
return gcd(b,a%b);
}
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b)
{
x=1,y=0;
return a;
}
LL r=exgcd(b,a%b,x,y),x0=x;
x=y;
y=x0-(a/b)*y;
return r;
}
LL china(LL *m,LL *a)
{
LL lcm=1,X=m[1],Y=a[1];
for(int i=1;i<=k;i++)
lcm=lcm/gcd(lcm,m[i])*m[i];
for(int i=2;i<=k;i++)
{
LL A=X,B=m[i],d,x,y,c=a[i]-Y;
d=exgcd(A,B,x,y);
if(c%d)
return -1;
LL mod=m[i]/d;
LL K=((x*c/d)%mod+mod)%mod;
Y=X*K+Y;
X=X*m[i]/d;
}
if(Y==0)
return lcm;
return Y;
}
bool check()
{
LL I=china(a,b),J;
if(I>n || I<=0)return false;
for(int i=1;i<=k;i++)b[i]=1-i;
J=china(a,b);
if(J+k-1>m || J<=0)return false;
for(int i=1;i<=k;i++)if(gcd(I,J+i-1)!=a[i])return false;
return true;
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=k;i++)
cin>>a[i];
if(check())cout<<"YES"<else cout<<"NO"<return 0;
}