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>
usingnamespace std;

longlong a, b, c, k;

longlong extgcd(longlong a, longlong b, longlong&x, longlong&y)
{
if (b ==0)
{
x
=1;
y
=0;
return a;
}
longlong d = extgcd(b, a % b, x, y);
longlong 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)
{
longlong x, y;
longlong t = b - a;
longlong h =1;
h
<<= k;
longlong 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);
}
return0;
}
原文地址:https://www.cnblogs.com/rainydays/p/2067773.html