题意
给你一个简单的循环for(int i=A;i!=B;i+=C),i是16位得数,问你循环结束的次数,如果是死循环的话,就输出死循环
思路
刚开始想简单的模拟一下,但是超时至少模拟2^k次循环,扩展欧几里得问题完美解决这个问题 题意循环可以转化成公式 ( A + xC ) mod (1<<K) = B 因为 题意中的A 肯定是小于(1<<k)的所以化简为 xC mod (1<<k) = B - A 这个就是扩展欧几里得定理求模线性方程 令D = B - A , n= (1<<k) 得 xC mod n = D 则 xC - yn =D 这就是 ax+b*y=c的扩展欧几里得定理解不定方程了
样例
Sample Input
3 3 2 16
3 7 2 16
7 3 2 16
3 4 2 16
0 0 0 0
Sample Output
0
2
32766
FOREVER
AC代码
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#define LL long long
using namespace std;
long long A,B,C,K;
long long x,y;
long long GCD;
long long tol;
void exgcd(long long a,long long b,long long &x,long long &y,long long &d)
{
if(!b)
{
d=a; x=1; y=0;
}
else
{
exgcd(b,a%b,y,x,d);
y-=x*(a/b);
}
}
int main()
{
while(scanf("%I64d %I64d %I64d %I64d",&A,&B,&C,&K)!=EOF&&(A||B||C||K))
{
if(A==B)
{
cout<<"0"<<endl;
continue;
}
B-=A;
tol=(1LL<<K);
exgcd(tol,C,x,y,GCD);
//无解
if(B%GCD!=0)
{
cout<<"FOREVER"<<endl;
continue;
}
else
{
x*=(B/GCD);
y*=(B/GCD);
y=(y%(tol/GCD)+tol/GCD)%(tol/GCD);
printf("%I64d\n", y);
}
}
return 0;
}
题源:poj.org/problem?id=…