zoukankan      html  css  js  c++  java
  • poj2115-Looooops-(扩展欧几里得定理)

    C Looooops
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions:33752   Accepted: 9832

    Description

    A Compiler Mystery: We are given a C-language style for loop of type 
    for (variable = A; variable != B; variable += C)
    
    statement;

    I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repeats statement followed by increasing the variable by C. We want to know how many times does the statement get executed for particular values of A, B and C, assuming that all arithmetics is calculated in a k-bit unsigned integer type (with values 0 <= x < 2k) modulo 2k

    Input

    The input consists of several instances. Each instance is described by a single line with four integers A, B, C, k separated by a single space. The integer k (1 <= k <= 32) is the number of bits of the control variable of the loop and A, B, C (0 <= A, B, C < 2k) are the parameters of the loop. 

    The input is finished by a line containing four zeros. 

    Output

    The output consists of several lines corresponding to the instances on the input. The i-th line contains either the number of executions of the statement in the i-th instance (a single integer number) or the word FOREVER if the loop does not terminate. 

    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
    翻译:在循环里,values值为a,每次加c,如果values不等于b,就继续循环下去,死循环输出forever,否则输出循环次数。所有运算都对无符号的k位二进制求模。
    解题过程
    设p=2^k
    起点为a,每次加c,对p求模若能等于b对p求模则有解,否则无解,输出forever
    有解的话设解为x
    (a+cx)%p = b%p
    a%p + cx%p = b%p
    cx%p = (b-a)%p
    cx%p + 0 = (b-a)%p
    cx%p + yp%p = (b-a)%p
    形如ax+by=gcd,扩展欧几里得定理。
     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<math.h>
     6 #include<string>
     7 #define ll long long
     8 #define inf 0x3f3f3f3f
     9 using namespace std;
    10 // ax + by = gcd(a,b)
    11 ll exgcd(ll a, ll b, ll &x, ll &y)//扩展欧几里德定理
    12 {
    13     if(b==0)//终有一次a%b传进来是0,递归出口
    14     {
    15         x=1;
    16         y=0;
    17         return a;
    18     }
    19     ll q=exgcd(b,a%b,y,x);
    20     //最终递归出来,y1=1,x1=0
    21     y=y-(a/b)*x;
    22     //后面的y相当于下一个递归的x2,x相当于下一个递归的y2,符合推导公式
    23     //x1=y2;   y1=x2-[a/b]*y2;
    24     return q;
    25 }
    26 
    27 int main()
    28 {
    29     ll a,b,c,k,p,x,y;
    30     while(scanf("%lld %lld %lld %lld",&a,&b,&c,&k)!=EOF&&(a+b+c+k))
    31     {
    32         p=1;
    33         for(ll i=1;i<=k;i++)
    34             p=p*2;
    35         ll gcd=exgcd(c,p,x,y);
    36         ll d=b-a;
    37         if(d%gcd)
    38             printf("FOREVER
    ");
    39         else
    40         {
    41             ll  multiple=d/gcd;///倍数
    42             p=p/gcd;///通解公式:x=x+b/gcd y=y-a/gcd
    43             x=( (x*multiple)%p+p )%p;///求最小正数解
    44             printf("%lld
    ",x);
    45         }
    46     }
    47     return 0;
    48 }
  • 相关阅读:
    详解java并发原子类AtomicInteger(基于jdk1.8源码分析)
    可见性、原子性和有序性
    Django基础之简单的前后端交互
    JDK1.8新特性之(三)--函数式接口
    JDK1.8新特性之(一)--Lambda表达式
    JDK1.8新特性之(二)--方法引用
    在IDEA创建类时自动创建作者日期等信息设定
    用batch调用DB2 CLPPlus执行多个SQL文
    windows7 设定开关机事件
    Mybatis显示修改数据库成功,数据库却没有修改
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10361943.html
Copyright © 2011-2022 走看看