ZOJ 3562 Alice's Sequence I

来源:互联网 发布:编程大括号 编辑:程序博客网 时间:2024/05/29 14:47

给出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 longusing 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;}