poj2115

题意:for(int i = a; i != b; i = (i + c) % (2 ^ k)) 能运行多少次。

分析:多次错的原因是1<<k,k很大会超出int;

扩展欧几里德,是求x * a + y * b = gcd(a, b) 的整数解。

这题我们可以认为是在mod 2 ^k 的条件下,

c * x = b - a; 求 x。

当然我们也可以直接理解为

本题是求 c * x + 2 ^ k * y = b - a;

先求c * x1 + 2 ^ k * y1 = gcd(c, 2 ^ k);

两端同乘(b - a) / gcd(c, 2 ^ k)即可变为原式

整理x的范围,输出即可

View Code
#include < iostream >
#include
< cstdio >
#include
< cstdlib >
#include
< cstring >
using namespace std;

long long a, b, c, k;

long long extgcd( long long a, long long b, long long & x, long long & y)
{
if (b == 0 )
{
x
= 1 ;
y
= 0 ;
return a;
}
long long d = extgcd(b, a % b, x, y);
long long t = x;
x
= y;
y
= t - a / b * y;
return d;
}

int main()
{
// freopen("t.txt", "r", stdin);
while (scanf( " %lld%lld%lld%lld " , & a, & b, & c, & k), (a | b | c | k) != 0 )
{
long long x, y;
long long t = b - a;
long long h = 1 ;
h
<<= k;
long long g = extgcd(c, h, x, y);
if (t % g != 0 )
{
printf(
" FOREVER\n " );
continue ;
}
x
*= t / g;
x
= (x % (h / g) + (h / g)) % (h / g);
printf(
" %lld\n " , x);
}
return 0 ;
}

你可能感兴趣的:(poj)