C Looooops
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 22260   Accepted: 6125

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

Source

 

大致题意:

对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束。

若在有限次内结束,则输出循环次数。

否则输出死循环。

解题思路:

题意不难理解,只是利用了 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。

以上方法的推导过程大家自己看《算法导论》。。。这里不证明,只直接使用。

注意:

计算n=2^k时,用位运算是最快的,1<<k (1左移k位)就是2^k

但是使用long long的同学要注意格式, 1ll<<k

使用__int64的同学要强制类型转换 (__int64)1<<k

不然会WA

 TLE代码:

#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
if(!b) return a;
return gcd(b,a%b);
}
ll quick_pow(ll x,ll n){
if(n==) return ;
else{
while(!(n&)){
n>>=;
x*=x;
}
}
ll result=x;
n>>=;
while(n){
x*=x;
if((n&)){
result*=x;
}
n>>=;
}
return result;
}
int main(){
ll a,b,c,k;
while(scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&k)==){
if(!a&&!b&&!c&&!k) break;
ll d=gcd(c,b-a);
if(b%d==){puts("FOREVER");continue;}
ll mod=quick_pow(,k);
printf("%I64d\n",(b-a+mod)%mod/c);
}
return ;
}

 AC代码:

#include<iostream>
#include<cstdio>
using namespace std;
#define LL long long
//d=ax+by,其中最大公约数d=gcd(a,n),x、y为方程系数,返回值为d、x、y
LL gcd(LL a,LL b,LL& x,LL& y){
if(b==){
x=;y=; //d=a,x=1,y=0,此时等式d=ax+by成立
return a;
}
LL d=gcd(b,a%b,x,y);
LL xt=x;
x=y;
y=xt-a/b*y;//系数x、y的取值是为满足等式d=ax+by
return d;
}
int main(){
LL A,B,C,k;
while(scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&k)==){
if(!A&&!B&&!C&&!k) break;
LL a=C;
LL b=B-A;
LL n=1ll<<k;
LL x,y;
LL d=gcd(a,n,x,y);//求a,n的最大公约数d=gcd(a,n)和方程d=ax+by的系数x、y
if(b%d!=) puts("FOREVER");//方程 ax=b(mod n) 无解
else{
x=(x*(b/d))%n;//方程ax=b(mod n)的最小解
x=(x%(n/d)+n/d)%(n/d);//方程ax=b(mod n)的最整数小解
printf("%I64d\n",x);
}
}
return ;
}

poj2115[扩展欧几里德]的更多相关文章

  1. C Looooops(poj2115+扩展欧几里德)

    C Looooops Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Pr ...

  2. POJ2115 C Looooops 扩展欧几里德

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ2115 题意 对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次 ...

  3. poj2115 Looooops 扩展欧几里德的应用

    好开心又做出一道,看样子做数论一定要先看书,认认真真仔仔细细的看一下各种重要的性质 及其用途,然后第一次接触的题目 边想边看别人的怎么做的,这样做出第一道题目后,后面的题目就完全可以自己思考啦 设要+ ...

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

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

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

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

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

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

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

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

  8. 51nod 1352 扩展欧几里德

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

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

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

随机推荐

  1. 利用PPPOE认证获取路由器中宽带账号密码

    前言 回家时买了一台极路由准备换掉家里老掉牙的阿里路由器,想进后台看一下宽带账号密码,咦???后台密码是什么来着??? 我陷入了沉思,家里的路由器一般都是pppoe拨号,而路由器在与pppoe认证服务 ...

  2. ZeroMQ使用学习记录(转)

    ZMQ简介 ZMQ(ØMQ.ZeroMQ, 0MQ)看起来像是一套嵌入式的网络链接库,但工作起来更像是一个并发式的框架.它提供的套接字可以在多种协议中传输消息,如线程间.进程间.TCP.广播等.你可以 ...

  3. 机器学习第1课:引言(Introduction)

    1.前言 Machine Learning(机器学习)是研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能. 它是人工智能的核心,是使计算机具有 ...

  4. 设置textField的placegolder的字体大小和字体颜色

           由于项目的主题颜色为灰黑色,所以当使用textField的时候,placeholder内的字体默认是灰色,当程序执行的时候,差点儿看不到.        翻来翻去找到一种比較简单地方法, ...

  5. perl学习笔记一

    标量数据 标量:数字.字符.可以存储在标量变量中也可以从文件和设备中读取. 数字:所有数字内部格式相同——双精度浮点数. 浮点数直接量:程序员在程序中直接键入的数字. 整数直接量:6129804028 ...

  6. Windows为什么双击打开‘我的电脑’, 没有了‘前进’‘ 后退’‘向上’等按钮?

    如图所示   点击查看 工具栏 标准按钮即可   左侧的数值虚线可以拖动到任意,还可以添加按钮如搜索,删除,复制,剪切等

  7. 借助backtrace和demangle实现异常类Exception

    C++的异常类是没有栈痕迹的,如果需要获取栈痕迹,需要使用以下函数: #include <execinfo.h> int backtrace(void **buffer, int size ...

  8. LoadRunner调用md5方法

    LoadRunner调用md5方法 上一篇 / 下一篇  2011-04-29 11:25:12 / 个人分类:Loadrunner 查看( 958 ) / 评论( 0 ) / 评分( 0 / 0 ) ...

  9. DialogFragment创建默认dialog

    代码地址如下:http://www.demodashi.com/demo/12228.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 前言 在我们项目的进行中不可避免 ...

  10. 使用PostMan快速生成代码

    Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件.关于PostMan的下载和使用网上有很多相关的博客介绍,本文主要介绍PostMan在进行模拟Http请求后可以根据需要的 ...