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没计算就加上去 = =。