您的位置:首页 > 编程语言

Codeforces 338D GCD Table 题解&代码

2016-01-19 21:08 274 查看
来自中国剩余定理的恶意

我其实什么都不知道…直接看题解

思路:

我们需要得到的是一个(x,y)组

其中x满足x%a[i]=0,y满足y%a[i]=1-i(对于所有a[]),这样就可以保证x是a[i]的最小公倍数且y+i-1是所有a[i]的倍数(同条件下得到的将是最小的y)

然后检验一下x和y是不是满足gcd(x,y+i-1)=ai…不满足说明我们求出的x和y是无效的,既然已得到的x和y无效,那么x的倍数与y的倍数必然无效——无效的原因一定是gcd(x,y+i-1)>ai【x是a[i]的倍数,y+i-1是a[i]的倍数】

**对了,中国剩余定理是抄模板的

#include<iostream>
#include<stdio.h>
#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) //方程x%m=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(void)
{
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(void)
{
cin>>n>>m>>k;
for(int i=1;i<=k;i++)
cin>>a[i];
if(check())cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: