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.
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).
Print a single word "YES", if the given sequence occurs in tableG, otherwise print "NO".
100 100 5 5 2 1 2 1
YES
100 8 5 5 2 1 2 1
NO
100 100 7 1 2 3 4 5 6 7
NO
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.
【分析】
扩展中国剩余定理。
【代码】
#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;
}