uva 12169 ex_gcd lrj—P316

来源:互联网 发布:淘宝客服转化率怎么算 编辑:程序博客网 时间:2024/06/12 23:13

题意:

给出一个递推式,

通过这个递推式可以得到一系列数,但是题目只给出位置为奇数的数字(从1开始),求偶数位置的数

题解:

枚举+扩展欧几里得

通过学习,发现刘汝佳的这本书简直是神书,以前在网上找了很久的资料才看懂的算法

他居然三言两语就解决了我疑惑的地方,以后就会用这个算法了

扩展欧几里得算法是解决    求解ax+by=c  这个函数的整数解 x  y

当 c 是gcd(x,y)的倍数的时候才有解

void ex_gcd(LL a,LL b,LL& gcd,LL& x,LL& y){    if(!b) gcd=a,x=1,y=0;    else   ex_gcd(b,a%b,gcd,y,x),y-=x*(a/b);}
代码中的字母就是上叙内容,非常简洁



#include<stdio.h>#define mod 10001#define LL long longLL num[210];void ex_gcd(LL a,LL b,LL& gcd,LL& x,LL& y){    if(!b) gcd=a,x=1,y=0;    else   ex_gcd(b,a%b,gcd,y,x),y-=x*(a/b);}int main(){    int n;    //freopen("in.txt","r",stdin);    while(scanf("%d",&n)!=EOF)    {        for(int i=0;i<n;i++)            scanf("%lld",&num[(i<<1)+1]);        if(n==1){            printf("%lld\n",num[1]);            printf("%lld\n",num[1]);            continue;        }        for(int a=0;a<=10000;a++){            LL gcd,x,y;            ex_gcd(a+1,mod,gcd,x,y);            if((num[3]-a*a*num[1])%gcd)                continue;            LL b=x*((num[3]-a*a*num[1])/gcd);            int p;            for(p=1;p<n;p++){                num[p<<1]=(a*num[(p<<1)-1]+b)%mod;                if(num[(p<<1)+1]!=(a*num[p<<1]+b)%mod)                    break;            }            num[n<<1]=(a*num[(n<<1)-1]+b)%mod;            if(p==n)  break;        }        for(int i=1;i<=n;i++)            printf("%lld\n",num[i<<1]);    }    return 0;}