PKU 2115 C Looooops(拓展欧几里德)


  • 原题链接:Here!

  • 题意:
    Description:
    对于循环语句:for(variable=A;variable!=B;variable+=C)statement;
    已知所有的数均要mod 2^k(即0<=x<2^k),给出A,B,C和k的值,计算并输出statement执行的次数,如果为无限次,那么直接输出“FOREVER”。
    Input:
    输入数据有多组,每组数据占一行,有四个整数A,B,C,k(0<=A,B,C<2^k),如上所述,输入以0 0 0 0终止。Output
    对于每组输入数据,输出“statement”执行的次数,如果为无限次,那么直接输出“FOREVER”。Description

    根据题意可以得出 A+C*t ≡ B( mod 1<<k )。需要注意的是1<<31会超出范围,所以应强制转换成long long
    下图是测试1<<k是否会爆掉


  • 代码:
    #include<iostream>
    using namespace std;
    
    typedef long long LL;
    LL exgcd(LL a,LL b,LL &x,LL &y){
    	if(b==0){
    		x=1; y=0; return a;
    	}
    	LL d = exgcd(b,a%b,x,y);
    	LL tmp = x;
    	x = y;
    	y = tmp - a/b*y;
    	return d;
    }
    int main(){
    	LL a,b,c,k,x,y;
    	while(cin>>a>>b>>c>>k && (a+b+c+k)){
    		LL m = (LL)1<<k;		// *** 1<<31位后,会超过int的最大值,需要转换为long long 
    		LL d = exgcd(c,m,x,y);
    		if((b-a)%d)
    			printf("FOREVER\n");
    		else{
    			LL tmp = m/d;
    			LL ans = x*(b-a)/d;
    			ans = (ans%tmp + tmp)%tmp;
    			cout<<ans<<endl;
    		}
    	} 
    	return 0;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值