题意: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;
}
#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;
}