HDU 1573 X问题
Problem Description
求在小于等于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)。
Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素。接下来两行,每行各有M个正整数,分别为a和b中的元素。
Output
对应每一组输入,在独立一行中输出一个正整数,表示满足条件的X的个数。
Sample Input
3
10 3
1 2 3
0 1 2
100 7
3 4 5 6 7 8 9
1 2 3 4 5 6 7
10000 10
1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9
Sample Output
1
0
3
-----------------------------------------------------------------分割线----------------------------------------------------------
题意
略(RT)
思想
扩展中国剩余定理
坑点
1、当excrt返回不为0时,答案即为(maxn-ans)/lcm+1,但excrt返回值为0时,答案为(maxn-ans)/lcm。
2、如果excrt返回值为-1时输出0。
3、我捣鼓了一天。。。一边跑excrt要一边判断ans有没有大于n,如果判断出ans>n了,直接return -1 ! ! !不然会炸LL。因为这个WA了一天的我瑟瑟发抖(这篇博客也是为了纪念一下苦逼的我)。
---------------------------------------------------分割线------------------------------------------------------------------------
#include <bits/stdc++.h>
#define MAXN 15
using namespace std;
typedef long long ll;
ll maxn;
ll lcm;
ll mul(ll a,ll b,ll p)//快乘
{
a%=p,b%=p;
if(p<=1e9)
return a*b%p;
return (a*b-(ll)(a/(long double)p*b+1e-8)*p+p)%p;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
ll gcd=exgcd(b,a%b,x,y);
ll tp=x;
x=y;
y=tp-a/b*y;
return gcd;
}
ll excrt(ll mi[],ll ai[],int n)
{
ll x,y;
ll M=mi[1],ans=ai[1];
for(int i=2; i<=n; i++)
{
ll a=M,b=mi[i],c=(ai[i]-ans%b+b)%b;
ll gcd=exgcd(a,b,x,y),bg=b/gcd;
if(c%gcd!=0)
return -1;
x=mul(x,c/gcd,bg);
ans+=x*M;
M*=bg;
ans=(ans%M+M)%M;
if(ans>maxn)
return -1;
}
lcm=M;
return (ans%M+M)%M;
}
int main()
{
ll m,t,i,d,ans;
ll mi[MAXN],ai[MAXN];
cin>>t;
while(t--)
{
scanf("%lld%lld",&maxn,&m);
for(i=1;i<=m;i++)
{
scanf("%lld",&mi[i]);
}
for(i=1;i<=m;i++)
{
scanf("%lld",&ai[i]);
}
ans=excrt(mi,ai,m);
if(ans==-1)
{
printf("0\n");
}
else
{
if(ans==0)
cout<<(maxn-ans)/lcm<<endl;
else
cout<<(maxn-ans)/lcm+1<<endl;
}
}
return 0;
}
忽略我的丑代码,凑合看看。