codeforces 338D GCD Table

时间:2021-12-01 00:40:19





D. GCD Table



time limit per test



memory limit per test



input



output


Consider a table G of size n × m such that G(i, j) = GCD(i, j) for all1 ≤ i ≤ n, 1 ≤ j ≤ m.GCD(a, b) is the greatest common divisor of numbersa andb.

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 numbers1 ≤ i ≤ n and1 ≤ j ≤ m - k + 1 should exist thatG(i, j + l - 1) = al for all1 ≤ l ≤ k.

Determine if the sequence a occurs in tableG.


Input



The first line contains three space-separated integers n, m and k (1 ≤ n, m ≤ 1012;1 ≤ k ≤ 10000). The second line containsk space-separated integers a1, a2, ..., ak (1 ≤ ai ≤ 1012).


Output



Print a single word "YES", if the given sequence occurs in tableG, otherwise print "NO".


Examples



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


Note



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 sequencea.

Sample 2. This time the width of table G equals 8. Sequencea




【分析】

扩展中国剩余定理。




¡ 转化问题:






¡ gcd(x,y)=a0, gcd(x,y+1)=a1, gcd(x,y+2)=a2……






¡ → y=-k(modak) 是原式有解的必要条件






¡ 代入 验证,若原始条件成立则 x,y 由中国 剩 余 定理可得 x=lcm({ ak }) , y 有唯一解






¡ 即 为答案,否则问题无解。







¡ 易知 x 最小为 lcm({ak}) ,在此时根据中国剩余定理 y 有唯一解,但是这个解只保证了 ak|x,y ,并没有保证 ak=gcd(x,y) ,由于随着 x,y 增大若干倍会更加不满足,所以此时是最有可能有解的情况,代入验证即可。









【代码】

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(ll i=j;i<=k;i++)
using namespace std;
const int mxn=10005;
ll n,m,k;
ll a[mxn],b[mxn],w[mxn];
inline ll gcd(ll x,ll y)
{
return x%y==0?y:gcd(y,x%y);
}
inline void exgcd(ll aa,ll bb,ll &x,ll &y)
{
if(!bb)
{
x=1,y=0;
return;
}
exgcd(bb,aa%bb,y,x);
y-=(aa/bb)*x;
}
inline ll inv(ll aa,ll bb)
{
ll x,y;
exgcd(aa,bb,x,y);
return (x%bb+bb)%bb;
}
inline ll mul(ll aa,ll bb,ll mod) //快速乘
{
ll ans=0;
if(bb<0) aa=-aa,bb=-bb;
while(bb)
{
if(bb&1) ans=(ans+aa)%mod;
bb>>=1;aa=(aa+aa)%mod;
}
return ans;
}
inline bool judge()
{
ll lcm=1,a1,a2,b1,b2,t,tmp=a[1];
fo(i,1,k)
{
b[i]=1-i;
t=gcd(lcm,a[i]);
lcm=lcm/t*a[i];
if(lcm>n) return 0;
}
fo(i,2,k)
{
a1=a[i-1],a2=a[i],b1=b[i-1],b2=b[i];
t=gcd(a1,a2);
if((b2-b1)%t!=0) return 0;
a[i]=a1/t*a2;
b[i]=inv(a1/t,a2/t);
b[i]=b[i];
b[i]=mul(b[i],(b2-b1)/t,a2/t);
b[i]=mul(b[i],a1,a[i]);
b[i]=(b[i]+b1)%a[i];
b[i]=(b[i]%a[i]+a[i])%a[i];
}
ll y=b[k];
if(!y) y+=a[k];
if(y+k-1>m) return 0;
fo(j,y,y+k-1)
if(gcd(lcm,j)!=w[j-y+1]) return 0;
return 1;
}
int main()
{
scanf("%I64d%I64d%I64d",&n,&m,&k);
fo(i,1,k) scanf("%I64d",&a[i]),w[i]=a[i];
if(judge()) printf("YES\n");
else printf("NO\n");
return 0;
}