【POJ-2115】C Looooops

108 阅读1分钟
题意

给你一个简单的循环for(int i=A;i!=B;i+=C),i是16位得数,问你循环结束的次数,如果是死循环的话,就输出死循环

 

思路

刚开始想简单的模拟一下,但是超时至少模拟2^k次循环,扩展欧几里得问题完美解决这个问题 题意循环可以转化成公式 ( A + xC ) mod (1<<K) = B 因为 题意中的A 肯定是小于(1<<k)的所以化简为 xC mod (1<<k) = B - A 这个就是扩展欧几里得定理求模线性方程 令D = B - A , n= (1<<k) 得 xC mod n = D 则 xC - yn =D 这就是 ax+b*y=c的扩展欧几里得定理解不定方程了

 

样例
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

 



 

AC代码
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#define LL long long
using namespace std;
long long A,B,C,K;
long long x,y;
long long GCD;
long long tol;

void exgcd(long long a,long long b,long long &x,long long &y,long long &d)
{
    if(!b)
    {
        d=a; x=1; y=0;
    }
    else
    {
        exgcd(b,a%b,y,x,d);
        y-=x*(a/b);
    }
}

int main()
{

    while(scanf("%I64d %I64d %I64d %I64d",&A,&B,&C,&K)!=EOF&&(A||B||C||K))
    {
        if(A==B)
        {
            cout<<"0"<<endl;
            continue;
        }
        B-=A;
        tol=(1LL<<K);
        exgcd(tol,C,x,y,GCD);
        //无解
        if(B%GCD!=0)
        {
            cout<<"FOREVER"<<endl;
            continue;
        }
        else
        {
            x*=(B/GCD);
            y*=(B/GCD);
            y=(y%(tol/GCD)+tol/GCD)%(tol/GCD);
            printf("%I64d\n", y);
        }
    }
    return 0;
}

 

题源:poj.org/problem?id=…