CF338D GCD Table (数论+扩展中国剩余定理)

原题:http://codeforces.com/contest/338/problem/D

题解:基本题意:gcd(i,x+j-1)=a[j] (j\varepsilon [1,k])是否存在。可以设:

x+j-1\equiv a[j](mod a[j])

整理得:

x\equiv a[j]-j+1(mod a[j])

这样就可以用合并方程的方法求出x和lcm,而行数i就为lcm。检验答案是否正确就可以了。

注意:这道题数较大要用到快速乘。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=11000;
ll n,m,a[N];
int p,flag;
ll exgcd(ll a,ll b,ll &x,ll &y){
	if(a==0){x=0;y=1;return b;}
	ll d,tx,ty;
	d=exgcd(b%a,a,tx,ty);
	x=ty-(b/a)*tx;
	y=tx;
	return d;
}
ll gcd(ll a,ll b){
	if(a==0) return b;
	return gcd(b%a,a);
}
ll mul(ll a,ll b,ll M){//快速乘 
	ll ans=0;ll f=1;
	if(a<0) f=-1*f,a=-a;
	if(b<0) f=-1*f,b=-b;
	while(b){
		if(b&1) ans=(ans+a)%M;
		a=(a+a)%M;b>>=1; 
	}
	return ans*f;
}
int main(){
//	freopen("b.in","r",stdin);
	scanf("%lld%lld%d",&n,&m,&p);
	for(int i=1;i<=p;i++) scanf("%lld",&a[i]);
	ll m1,m2,b1,b2,d,x,y,k;
	m1=a[1];b1=a[1];flag=0;
	for(int i=2;i<=p;i++){
		m2=a[i];b2=a[i]-i+1;k=b2-b1;
		d=exgcd(m1,m2,x,y);
		if(k%d) {flag=1;break;}
		x=mul(x,k/d,m2/d);//快速乘 
		x=(x+(m2/d))%(m2/d);
		b1=m1*x+b1;
		m1=m1/d*m2; 
	} 
	if(b1==0) b1=m1;
	if(m1>n) flag=1;
	if(b1>m-p+1) flag=1;
	for(int i=1;i<=p;i++) 
		if(gcd(b1+i-1,m1)!=a[i]){
			flag=1;break;
		}
	if(flag) printf("NO\n");
	else printf("YES\n"); 
	return 0;
}

 

转载于:https://www.cnblogs.com/Exception2017/p/10252089.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值