codeforces 338D GCD Table
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
Determine if the sequence a occurs in tableG.
InputThe 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
Print a single word "YES", if the given sequence occurs in tableG, otherwise print "NO".
Examples Input100 100 5 5 2 1 2 1Output
YESInput
100 8 5 5 2 1 2 1Output
NOInput
100 100 7 1 2 3 4 5 6 7Output
NONote
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;
}