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 }
  • 相关阅读:
    Pandas 中对列 groupby 后进行 sum() 与 count() 区别及 agg() 的使用方法
    数据预处理 | python 第三方库 imblearn 处理样本分布不均衡问题
    数据预处理 | 使用 pandas.to_datetime 处理时间类型的数据
    CSS自定义文件上传按钮样式,兼容主流浏览器
    php实现计划任务
    windows环境下为php打开ssh2扩展
    vmware上linux连网(centos6.3、ubuntu14测试通过)
    如何实现打开网页自动弹出QQ对话框
    php输出最近N个月的起至时间戳
    内部div自动扩张剩余宽度(包含固定宽度div和自适应宽度div)
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10361943.html
Copyright © 2011-2022 走看看