zoukankan      html  css  js  c++  java
  • R

    题目大意:很好理解,一个for循环语句,从a开始到b结束,步长是c,模数是pow(2,k)

         问,最少循环多少次,才能到达b,如果永远都到不了b,输出FOREVER

    题解:其实就是求一个线性方程,cx=b( mod p)。问x最小是多少。

    这个线性方程怎么来的呢?从a开始假设我们走了x步,到达了b,则a+cx=b( mod p)将a移到右边可得cx=(b-a)( mod p)。

    这个线性方程怎么解呢? 假设cx在取了y次模得到了(b-a),那么cx-py=(b-a),也就是解这个二元一次方程。

    很容易想到用EXGCD。然后就是关于x的最小值,计算出x后,只需要去一次模就可以了。

    code:

    //#include<bits/stdc++.h>
    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll; 
    void exgcd(ll a,ll b,ll &x,ll &y){ 
        if(b==0) {
            x=1;y=0;
        }
        else {
            exgcd(b,a%b,y,x);
            y-=a/b*x;
        }
    }
    int main(){
        ll A,B,C,k;
        while(cin>>A>>B>>C>>k){
            if(A==0&&B==0&&C==0&&k==0) break; 
            ll p=(ll)1<<k;
            ll b=B-A;
            ll c=C;
            if(c==0&&A!=B){
                cout<<"FOREVER"<<endl;
                continue ;
            }
            if(b%__gcd(c,p)==0){
                ll d=__gcd(c,p);
                b/=d;c/=d;p/=d;
                ll x,y;
                exgcd(c,p,x,y);x=x*b%p;
                cout<<(x+p)%p<<endl;
            }
            else puts("FOREVER");
        } 
        return 0;
    }

    对拓展欧里解决线性问题的总结:

      1 类似于:ax+by=c.该方程有解的条件是 c%gcd(a,b)=0,然后a1=a/gcd(a,b),b1=b/gcd(a,b),c1=c/gcd(a,b),将方程转换成了a1x+b1y=c1。然后我们可以根据exgcd求出a1x+b1y=1时的x,然后只需要让x*=c1就是该方程的解,注意,这个解只是其中一个,该方程的通解为x=x+k*b,y=y-k*a。

  • 相关阅读:
    python全栈学习--day48
    python全栈学习--day47(HTML-----高级选择器与盒子模型等
    python全栈学习--day46(html---列表,标签,表格,表单,css引入与基本选择器)
    python-面向对象编程设计与开发
    python-知识点的复习2
    python-知识点的复习
    python-re模块
    python-logging模块
    python-hash和md5算法
    python-配置文件的处理configpasser模块
  • 原文地址:https://www.cnblogs.com/Accepting/p/12584386.html
Copyright © 2011-2022 走看看