C Looooops POJ - 2115(扩展欧几里得)

21 篇文章 0 订阅

题目地址:http://poj.org/problem?id=2115
题意:for (variable = A; variable != B; variable += C)
variable= variable%2k.
问循环是否能够终止,以及循环的次数。
思路:扩展欧几里得的基础题。
假设循环x次,则a+cx=b(mod 2^k)
cx=(b-a)(mod 2^k)
cx+2ky=(b-a) (y任意整数)
判断(b-a)是否整除gcd(c,2k),否的话方程无解,循环不能够终止:是的话,进行扩展欧几里得求解即可。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
void Ex_gcd(long long  a,long long  b, long long &x,long long &y)
{
    if(b == 0)//µÝ¹é³ö¿Ú
    {
        x = 1;
        y = 0;
        return;
    }
   long long x1, y1;
    Ex_gcd(b, a%b, x1, y1);
    x = y1;
    y = x1-(a/b)*y1;
}
long long quick(int k)
{
    long long b=1;
    long long m=2;
    while(k)
    {
        if(k&1)
            b=b*m;
        m=m*m;
        k=k>>1;
    }
    return b;
}
long long gcd(long long a,long long b)
{
    return b?gcd(b,a%b):a;
}
int main()
{

      long long k,a,b,c;
      while(scanf("%lld%lld%lld%lld",&a,&b,&c,&k)!=EOF)
      {
          if(k==0&&a==0&&b==0&&c==0)
            break;
          long long m=quick(k);
          long long g=gcd(c,m);
          long long n=b-a;
          if(n%g)
          {
              printf("FOREVER\n");
              continue;
          }
          long long x,y;
          Ex_gcd(c,m,x,y);
          m=m/g;
          x=x*(n/g);
          x=(x%m+m)%m;
          printf("%lld\n",x);
      }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值