poj 2115 C Looooops

// 推广的欧几里德算法

#include <iostream>
using namespace std;


__int64 exgcd(__int64 a,__int64 b,__int64 &x,__int64 &y)
{
 if (b==0)
 { 
  x=1;y=0;
  return a;
 }
 __int64 d=exgcd(b,a%b,x,y);
 __int64 temp=x;
 x=y;
 y=temp-(a/b)*y;
 return d;
}

 
int main()
{
 __int64 a,b,c,k;
 while (scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&k) )
 {
 
  if (!a && !b && !c && !k) break;
  if (a==b)
  {
   printf("0/n");
   continue;
  }
  if (c==0)
  {
   printf("FOREVER/n");
   continue;
  }
  __int64 B=c;
  __int64 A=(__int64)1<<k;
  __int64 C=b-a;
  __int64 x,y;
  __int64 d=exgcd(A,B,x,y);
  if (C%d)   //无解的情况(可以查看算法导论)
  {
   printf("FOREVER/n");
   continue;
  }

  
  y=(y*(C/d))%A;     //得到第一个解

  
  __int64 t=A/d;
  y=(y%t+t)%t;   //C++的%运算符好像对负数的模运算会先算绝对值再把负号加上去
                 //用这个式子可以保证得到最小的正余数

  
  printf("%I64d/n",y);
 }

   
      


 return 0;
}
 

你可能感兴趣的:(poj 2115 C Looooops)