POJ2115(扩展欧几里得)

C Looooops

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 23700   Accepted: 6550

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

由题意易得(a+cx)%2^k==b,求x最小值。可得同余方程c*x=(b-a)mod2^k。

 1 //2016.8.17
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define ll long long
 6
 7 using namespace std;
 8
 9 ll ex_gcd(ll a, ll b, ll& x, ll& y)//扩展欧几里得
10 {
11     if(b==0)
12     {
13         x = 1;
14         y = 0;
15         return a;
16     }
17     ll ans = ex_gcd(b, a%b, x, y);
18     ll tmp = x;
19     x = y;
20     y = tmp-(a/b)*y;
21     return ans;
22 }
23
24 int main()
25 {
26     ll a, b, c, x, y, res, n;
27     int k;
28     while(scanf("%lld%lld%lld%d", &a, &b, &c, &k)!=EOF)
29     {
30         if(!a&&!b&&!c&&!k)
31           break;
32         n = (ll)1<<k;
33         res = ex_gcd(c, n, x, y);
34         cout<<res<<endl<<x<<endl;
35         if((b-a)%res!=0)cout<<"FOREVER"<<endl;
36         else
37         {
38             x = x*(b-a)/res%n;//方程ax=b-a(mod n)的最小解
39             ll tmp = n/res;
40             x = (x%tmp+tmp)%tmp;//最小正数解
41             printf("%lld\n", x);
42         }
43     }
44
45     return 0;
46 }
时间: 2024-10-08 22:05:33

POJ2115(扩展欧几里得)的相关文章

poj2115 C Looooops——扩展欧几里得

题目:http://poj.org/problem?id=2115 就是扩展欧几里得呗: 然而忘记除公约数... 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; ll A,B,C,k,a,b,x,y,g,s; ll gcd(ll a,ll b){return a%b?gcd(b,a%b):b;} void exgc

UVa 11768 格点判定(扩展欧几里得求线段整点)

https://vjudge.net/problem/UVA-11768 题意: 给定两个点A(x1,y1)和B(x2,y2),均为0.1的整数倍.统计选段AB穿过多少个整点. 思路: 做了这道题之后对于扩展欧几里得有了全面的了解. 根据两点式公式求出直线 ,那么ax+by=c 中的a.b.c都可以确定下来了. 接下来首先去计算出一组解(x0,y0),因为根据这一组解,你可以写出它的任意解,其中,K取任何整数. 需要注意的是,这个 a' 和 b' 是很重要的,比如说 b' ,它代表的是x每隔 b

【扩展欧几里得】BZOJ1477-青蛙的约会

一直在WA,后来我发现我把东西看反了-- [题目大意] 给出一个长度为L的环状坐标轴,两个点开始时位于(X,0).(Y,0).每次两点分别往右边移动m和n,问能否相遇? [思路] 由题意,可得: X+mt=Y+nt(mod L) (X+mt)-(Y+nt)=L*k (n-m)t+L*k=X-Y. 可以用扩展欧几里得来做.具体来说,显然要满足n-m和L的最大公约数(记为d)要整除X-Y,否则无解.这个可以在扩展欧几里得中求出. 式子可以化简为:[(n-m)/d]*t+(L/d)*k=(X-Y)/d

POJ 1061 青蛙的约会 扩展欧几里得

扩展欧几里得模板套一下就A了,不过要注意刚好整除的时候,代码中有注释 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; ll exgcd(ll a, ll b, ll&x, ll&y) { if (b ==

POJ 2115 (模线性方程 -&gt; 扩展欧几里得)

题意: for(i=A ; i!=B ;i +=C)循环语句,问在k位操作系统中循环结束次数. 若在有则输出循环次数. 否则输出死循环. 存在这样的情况:i= 65533 :i<=2:i+= 4:时i = 2: 由模线性方程->扩展欧几里得 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> using

POJ 2115 C Looooops(扩展欧几里得应用)

题目地址:POJ 2115 水题..公式很好推.最直接的公式就是a+n*c==b+m*2^k.然后可以变形为模线性方程的样子,就是 n*c+m*2^k==b-a.即求n*c==(b-a)mod(2^k)的最小解.(真搞不懂为什么训练的时候好多人把青蛙的约会都给做出来了,这题却一直做不出来.....这两道不都是推公式然后变形吗.....) 代码如下: #include <iostream> #include <cstdio> #include <string> #incl

【64测试20161112】【Catalan数】【数论】【扩展欧几里得】【逆】

Problem: n个人(偶数)排队,排两行,每一行的身高依次递增,且第二行的人的身高大于对应的第一行的人,问有多少种方案.mod 1e9+9 Solution: 这道题由1,2,5,14 应该想到Catalan数,但是我却花了两个小时去找递推式. 首先 Catalan数 : 基本规律:1,2,5,14,42,132,.......... 典型例题: 1.多边形分割.一个多边形分为若干个三角形有多少种分法. C(n)=∑(i=2...n-1)C(i)*C(n-i+1) 2.排队问题:转化为n个人

HDU1576(扩展欧几里得)

A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4252    Accepted Submission(s): 3277 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1). Input 数据的第一行是一个T

gcd,扩展欧几里得,中国剩余定理

1.gcd: int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } 2.中国剩余定理: 题目:学生A依次给n个整数a[],学生B相应给n个正整数m[]且两两互素,老师提出问题:有一正整数ans,对于每一对数,都有:(ans-a[i])mod m[i]=0.求此数最小为多少. 输入样例: 1 10 2 3 1 2 3 2 3 5 8 1 2 3 4 5 6 7 8 97 89 67 61 59 53 47 88 12 1 2 3 4 5 6 7 8 9