您的位置:首页 > 其它

HDU 1573 X问题 中国剩余定理

2016-02-16 15:16 148 查看
链接:pid=1573">http://acm.hdu.edu.cn/showproblem.php?

pid=1573

题意:求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 < a[i] <= 10)。

思路:中国剩余定理的模板题(全部除数相互不互质版),假设找不到这种数或者最小的X大于N。输出零。

资料:http://yzmduncan.iteye.com/blog/1323599/

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#define PI acos(-1.0)
#define maxn 10005
#define INF 0x7fffffff
#define eps 1e-8
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
LL MOD;
LL extend_gcd(LL a, LL b, LL &x, LL &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
LL r=extend_gcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
return r;
}
LL inv(LL a,LL m)
{
LL d,x,y;
d=extend_gcd(a,m,x,y);
if (d==1)
{
x=(x%m+m)%m;
return x;
}
else return -1;
}
LL gcd(LL a,LL b)
{
return b==0?a:gcd(b,a%b);
}
bool merge(LL a1,LL m1,LL a2,LL m2,LL &a3,LL &m3)
{
LL d=gcd(m1,m2);
LL c=a2-a1;
if(c%d)
return false;
c=(c%m2+m2)%m2;
c/=d;
m1/=d;
m2/=d;
c*=inv(m1,m2);
c%=m2;
c*=m1*d;
c+=a1;
m3=m1*m2*d;
a3=(c%m3+m3)%m3;
return true;
}
LL CRT_next(LL a[],LL m[],int n)
{
LL a1=a[0],m1=m[0],a2,m2;
for(int i=1;i<n;i++)
{
LL aa,mm;
a2=a[i],m2=m[i];
if(!merge(a1,m1,a2,m2,aa,mm))
return -1;
a1=aa;
m1=mm;
}
MOD=m1;
LL aa=(a1%m1+m1)%m1;
if(aa==0)
aa+=m1;
return aa;
}
int main()
{
int T;
LL a[55],b[55];
scanf("%d",&T);
for(int ii=1; ii<=T; ii++)
{
int tot;
LL t1;
scanf("%I64d%d",&t1,&tot);
for(int i=0; i<tot; i++)
scanf("%I64d",&a[i]);
for(int i=0; i<tot; i++)
scanf("%I64d",&b[i]);
if(tot==1)
{
if(b[0]==0)
b[0]+=a[0];
if(t1<b[0])
printf("0\n");
else
printf("%I64d\n",(t1-b[0])/a[0]+1);
}
else
{
LL ans=CRT_next(b,a,tot);
if(ans==-1)
printf("0\n");
else if(ans>t1)
printf("0\n");
else
printf("%I64d\n",(t1-ans)/MOD+1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: