C Looooops
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 23673   Accepted: 6540

Description

A Compiler Mystery: We are given a C-language style for loop of type

for (variable = A; variable != B; variable += C)

statement;

I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repeats statement followed by increasing the variable by C. We want to know how many times does the statement get executed for particular values of A, B and C, assuming that all arithmetics is calculated in a k-bit unsigned integer type (with values 0 <= x < 2k) modulo 2k.

Input

The input consists of several instances. Each instance is described by a single line with four integers A, B, C, k separated by a single space. The integer k (1 <= k <= 32) is the number of bits of the control variable of the loop and A, B, C (0 <= A, B, C < 2k) are the parameters of the loop.

The input is finished by a line containing four zeros.

Output

The output consists of several lines corresponding to the instances on the input. The i-th line contains either the number of executions of the statement in the i-th instance (a single integer number) or the word FOREVER if the loop does not terminate. 

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

参考题解:http://blog.csdn.net/lyy289065406/article/details/6648546

利用了 k位存储系统 的数据特性进行循环。

例如int型是16位的,那么int能保存2^16个数据,即最大数为65535(本题默认为无符号),

当循环使得i超过65535时,则i会返回0重新开始计数

如i=65534,当i+=3时,i=1

其实就是 i=(65534+3)%(2^16)=1

有了这些思想,设对于某组数据要循环x次结束,那么本题就很容易得到方程:

x=[(B-A+2^k)%2^k] /C

即 Cx=(B-A)(mod 2^k)  此方程为 模线性方程,本题就是求X的值。

下面将结合《算法导论》第2版进行简述,因此先把上面的方程变形,统一符号。

令a=C

b=B-A

n=2^k

那么原模线性方程变形为:

ax=b (mod n)

该方程有解的充要条件为 gcd(a,n) | b ,即 b% gcd(a,n)==0

令d=gcd(a,n)

有该方程的 最小整数解为 x = e (mod n/d)

其中e = [x0 mod(n/d) + n/d] mod (n/d) ,x0为方程的最小解

那么原题就是要计算b% gcd(a,n)是否为0,若为0则计算最小整数解,否则输出FOREVER

当有解时,关键在于计算最大公约数 d=gcd(a,n) 与 最小解x0

参考《算法导论》,引入欧几里得扩展方程  d=ax+by ,

通过EXTENDED_EUCLID算法(P571)求得d、x、y值,其中返回的x就是最小解x0,求d的原理是辗转相除法(欧几里德算法)

再利用MODULAR-LINEAR-EQUATION-SOLVER算法(P564)通过x0计算x值。注意x0可能为负,因此要先 + n/d 再模n/d。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define LL long long LL x,y;
LL e_gcd(LL a,LL b)
{
if(b==)
{
x=;
y=;
return a;
}
LL r=e_gcd(b,a%b);
LL t=x;
x=y;
y=t-a/b*y;
return r;
} int main()
{
LL A,B,C,k;
while(scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&k)!=EOF)
{
LL a=C;
LL n=1ll;
//cout<<n<<endl;
LL b=B-A;
if(A+B+C+k==)
break;
for(int i=; i<k; i++)
n<<=;
LL g=e_gcd(a,n);
if(b%g)
{
printf("FOREVER\n");
continue;
}
LL t=b/g;
x*=t;
x=(x%(n/g)+(n/g))%(n/g);
printf("%I64d\n",x);
}
return ;
}

POJ_2115_扩展欧几里德的更多相关文章

  1. (扩展欧几里德算法)zzuoj 10402: C.机器人

    10402: C.机器人 Description Dr. Kong 设计的机器人卡尔非常活泼,既能原地蹦,又能跳远.由于受软硬件设计所限,机器人卡尔只能定点跳远.若机器人站在(X,Y)位置,它可以原地 ...

  2. [BZOJ1407][NOI2002]Savage(扩展欧几里德)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1407 分析: m,n范围都不大,所以可以考虑枚举 先枚举m,然后判定某个m行不行 某个 ...

  3. 欧几里德与扩展欧几里德算法 Extended Euclidean algorithm

    欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd( ...

  4. 51nod 1352 扩展欧几里德

    给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2},{N,1}.求出有多少个集合满足:第一个元素是A的倍数且第二个元素是B的倍数. 提示: 对于第二组测试数据,集合分别 ...

  5. CF 7C. Line(扩展欧几里德)

    题目链接 AC了.经典问题,a*x+b*y+c = 0整数点,有些忘记了扩展欧几里德,复习一下. #include <cstdio> #include <iostream> # ...

  6. poj2142-The Balance(扩展欧几里德算法)

    一,题意: 有两个类型的砝码,质量分别为a,b;现在要求称出质量为d的物品, 要用多少a砝码(x)和多少b砝码(y),使得(x+y)最小.(注意:砝码位置有左右之分). 二,思路: 1,砝码有左右位置 ...

  7. poj2115-C Looooops(扩展欧几里德算法)

    本题和poj1061青蛙问题同属一类,都运用到扩展欧几里德算法,可以参考poj1061,解题思路步骤基本都一样.一,题意: 对于for(i=A ; i!=B ;i+=C)循环语句,问在k位存储系统中循 ...

  8. poj1061-青蛙的约会(扩展欧几里德算法)

    一,题意: 两个青蛙在赤道上跳跃,走环路.起始位置分别为x,y. 每次跳跃距离分别为m,n.赤道长度为L.两青蛙跳跃方向与次数相同的情况下, 问两青蛙是否有方法跳跃到同一点.输出最少跳跃次数.二,思路 ...

  9. HDU 1576 A/B【扩展欧几里德】

    设A/B=x,则A=Bx n=A%9973=A-9973*y=Bx-9973*y 用扩展欧几里德求解 #include<stdio.h> #include<string.h> ...

随机推荐

  1. Haybale Guessing

    Haybale Guessing Time Limit: 1000MS   Memory Limit: 65536K       Description The cows, who always ha ...

  2. 学习笔记——TCP“三次握手”和“四次挥手”,简单介绍

    TCP/IP协议中,TCP协议提供可靠的连接服务,采用“三次握手”建立一个连接. (1)第一次握手:客户端发送SYN包(SYN=j)到服务器,并进入SYN_SEND状态,等待服务器确认. (2)第二次 ...

  3. Java设计模式——外观模式

    JAVA 设计模式 外观模式 用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构

  4. N天学习一个linux命令之rsync

    用途 主要用于本地和远程主机同步文件 特性 1 使用增量传输算法(delta-transfer algorithm) 2 支持ssh,rsync协议 3 可以用于本地同步文件 4 本地和远程主机都需要 ...

  5. maven的启动类和MAVEN_OPTS参数

    maven的启动类和MAVEN_OPTS参数 在mvn.cmd的155行, set CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launc ...

  6. Unreal Engine 4 Camera Lag(摄影机延迟)

    以官方的Third Person Template为样例,Character蓝图中的USpringArmComponent就实现了摄影机和场景碰撞和交互等大部分的功能了. 要实现摄影机延时,仅仅须要改 ...

  7. Hilbert曲线简单介绍及生成算法

    Hilbert曲线 Hilbert曲线是一种填充曲线,相似的填充曲线还包含Z曲线.格雷码等其它方法.Hilbert曲线根据自身空间填充曲线的特性,能够线性地贯穿二维或者更高维度每一个离散单元.而且只穿 ...

  8. Oracle VM VirtualBox使用的注意事项

    Oracle VM VirtualBox使用的注意事项 Oracle VM VirtualBox 上克隆虚拟机 方法一 1.复制源虚拟里的 vdi 文件到新的目录 2.命令行进入 Oracle VM  ...

  9. curses-键盘编码-openssl加解密【转】

    本文转载自;https://zhuanlan.zhihu.com/p/26164115 1.1 键盘编码 按键过程:当用户按下某个键时, 1.键盘会检测到这个动作,并通过键盘控制器把扫描码(scan ...

  10. Java之POI读取Excel的Package should contain a content type part [M1.13]] with root cause异常问题解决

    Java之POI读取Excel的Package should contain a content type part [M1.13]] with root cause异常问题解决 引言: 在Java中 ...