给出K个模方程,x = ai % mi,求出x在L,R区间内的解的个数,然后输出这些解,超过100个就只输出前100个解。
这题和POJ 2891很像,那题只要求出最小的正解,于是只需要在那题的基础上改下就行了。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stack>
#include<queue>
#include<math.h>
#include<cstdio>
#define LL long long
using namespace std;
long long a[10010];
long long m[10010];
long long ans[1000];
long long ext_gcd(long long a,long long b,long long &x,long long &y)
{
long long t,ret;
if (!b)
{
x=1,y=0;
return a;
}
ret=ext_gcd(b,a%b,x,y);
t=x,x=y,y=t-a/b*y;
return ret;
}
int main()
{
int k;
long long a1,r1,a2,r2,lcm;
long long d,x,y,L,R;
while(~scanf("%d",&k))
{
bool flag=false;
for(int i=1;i<=k;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=k;i++)
scanf("%lld",&m[i]);
scanf("%lld%lld",&L,&R);
a1=a[1];
r1=m[1];
if(k==1 && r1>=a1) { puts("0");continue; }
for(int i=2;i<=k;++i)
{
a2=a[i];
r2=m[i];
if(flag)
continue;
d=ext_gcd(a1,a2,x,y);
if((r2-r1)%d)
flag=true;
a2=a2/d;
r1=((x*((r2-r1)/d)%a2+a2)%a2)*a1+r1;
a1=a2*a1;
}
if(flag)
printf("0\n");
else
{
long long ans1=r1%a1;
lcm=a1;
if(ans1<L)
ans1=(L-ans1)/lcm*lcm+ans1;
if(ans1<L) ans1+=lcm;
if(ans1>R) { puts("0");continue; }
LL cnt=(R-ans1)/lcm+1;
printf("%lld\n%lld",cnt,ans1);
for(int i=2;i<=100 && i<=cnt;i++)
{
ans1+=lcm;
printf(" %lld",ans1);
}
puts("");
}
}
return 0;
}