zoukankan      html  css  js  c++  java
  • poj2115(扩展欧基里德定理)

    题目链接:https://vjudge.net/problem/POJ-2115

    题意:模拟for循环for(int i=A;i!=B;i+=C),且数据范围为k位无符号数以内,即0~1<<k-1,如果能循环为有限次则输出循环次数,否则输出FOREVER。

    思路:典型的扩展欧基里德题。题意即求Cx=B-A (mod 1<<k),可化为Cx+(1<<k)y=B-A (mod 1<<k)。不访令a=C,b=1<<k,c=B-A,即求ax+by=c (mod b)的解x。根据扩展欧基里德定理,该方程有解的条件为gcd(a,b)|c。令d=gcd(a,b),则ax0+by0=d可通过扩展欧基里德计算得到x0,y0和d的值。则原问题的解x=(c/d*x0%(b/d)+b/d)%(b/d)。理由是,c/d*x0可能超出1<<k(b)的范围,注意到ax+by=d等价与a(x+m*b/d)+b(y-m*a/d)=d,m为任意值,即通过对b/d取模能得到最小非负整数解,因为可能为负值,所以取模后仍要加上b/d,并再次取模。

    AC代码:

     1 #include<cstdio>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 LL A,B,C,a,b,c,k;
     6 
     7 void ex_gcd(LL a,LL b,LL &x,LL &y,LL &d){
     8     if(!b) x=1,y=0,d=a;
     9     else{ex_gcd(b,a%b,y,x,d);y-=x*(a/b);}
    10 }
    11 
    12 int main(){
    13     while(~scanf("%lld%lld%lld%lld",&A,&B,&C,&k),k){
    14         a=C,b=1LL<<k;c=(B-A)%b;
    15         LL x,y,d;
    16         ex_gcd(a,b,x,y,d);
    17         if(c%d==0)
    18             printf("%lld
    ",(c/d*x%(b/d)+b/d)%(b/d));
    19         else printf("FOREVER
    ");
    20     }
    21     return 0;
    22 }
  • 相关阅读:
    CentOS7 防火墙firewalld详细操作
    bootstrap-datetimepicker 滚动错位问题
    Contos更换python版本
    centos7.3下使用yum 安装pip
    备注
    jenkins与SVN 问题记录
    kafka配置
    Jenkins 与github配置
    nginx File not found 错误
    nginx 总结
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10738741.html
Copyright © 2011-2022 走看看