C Looooops-扩展欧几里德

update@2011-09-17

#include <iostream>
#include <cstdio>
using namespace std;
long long gcd(long long a,long long b){
    return b ? gcd( b,a % b ) : a;
}

long long Extened_Euclid(long long a,long long b,long long &x,long long &y){
    if(b == 0){
        x = 1; y = 0; return a;
    }
    else{
        long long gcd,x1,y1;
        gcd = Extened_Euclid(b,a%b,x1,y1);
        x = y1; y = x1 - (a/b)*y1;
        return gcd;
    }
}
int main(){
    int A,B,C,K;
    while(scanf("%d%d%d%d",&A,&B,&C,&K) && !(A==0 &&B==0 && C==0 &&K==0)){
        //x*C = (B-A) (mod 1<<K)
        long long a,b,n,d,x,y,rs,step; n = (1LL<<K);
        a = C;b = ((B-A)%n+n)%n;
        d = gcd(a,n);
        if(b % d != 0){
            printf("FOREVER\n");continue;
        }
        //ar + sn = gcd(a,n);解出 r s
        Extened_Euclid(a,n,x,y);
        rs = x*b/d;step = n/d;
        printf("%lld\n",(rs%step+step)%step);

    }
    return 0;
}


题目链接:C Looooops
标准做法是扩展欧几里得解同余方程,解出一个解之后算一个最小解就是答案。先看wiki上的线性同余方程的词条,再看扩展欧几里德,博客中有一篇写了欧几里得的模板 。long long 送了很多WA,更二的是开始的时候n没计算就加上去 = =。