hdu1573 X问题 中国剩余定理

来源:互联网 发布:淘宝货款 编辑:程序博客网 时间:2024/03/28 22:10


题意:给出两个数 N,M,再给出M个除数NUM[],再给出对应的M个余数REMAIN[] 。

求在区间[1,N]内有多少个数满足所有情况。


除了应用扩展欧几里德和中国剩余定理,要注意的是可以将M个除数变成两个除数,然后更新除数和余数。

代码如下:


//============================================================================// Name        : hdu1573.cpp// Author      : ssslpk// Version     :// Copyright   : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================#include <iostream>#include<cstdio>#include<cmath>using namespace std;#define FOR(i,s,m) for(int i=s;i<m;i++)#define int64 long long#define N 12int64 d;int64 num[N];int64 remain[N];int64 gcd(int64 a,int64 b){return b?  gcd(b,a%b):a;}int64 exgcd(int64 a,int64 b,int64 &x,int64 &y){if(b==0){x=1;y=0;return a;}d=exgcd(b,a%b,x,y);int64 temp=x;x=y;y=temp-a/b*y;return d;}int64 china(int64 m,int64 num[],int64 remain[],int64 &lcm ){bool flag=true;int64 a,b,c,x,y,remain1,remain2;a=num[0];remain1=remain[0];FOR(i,1,m){b=num[i];remain2=remain[i];c=remain2-remain1;d=exgcd(a,b,x,y);if(c%d)flag=false;x=((x*(c/d))%b+b)%b;remain1=remain1+a*x;a=(a*b)/d;remain1=(remain1%a+a)%a;}lcm=a;if(!flag)return -1;return remain1;}int main() {int cas;cin>>cas;while(cas--){int64 n,m;int64 lcm;int64 ans,cnt=0;cin>>n>>m;FOR(i,0,m) cin>>num[i];FOR(i,0,m) cin>>remain[i];ans=china(m,num,remain,lcm);if(ans==-1||n<ans){cout<<0<<endl;continue;}cnt=(n-ans)/lcm+1;if(ans==0)cnt--;cout<<cnt<<endl;}return 0;}


原创粉丝点击