1. 程式人生 > >codeforces 338D GCD Table

codeforces 338D GCD Table

 D. GCD Table time limit per test 1 second memory limit per test 256 megabytes input standard input output standard 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 doesn't occur there.

【分析】

擴充套件中國剩餘定理。

¡轉化問題: ¡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;
}