POJ2115 C Looooops(线性同余方程)

无符号k位数溢出就相当于mod 2k,然后设循环x次A等于B,就可以列出方程:

$$ Cx+A \equiv B \pmod {2^k} $$ $$ Cx \equiv B-A \pmod {2^k} $$

最后就用扩展欧几里得算法求出这个线性同余方程的最小非负整数解。

 1 #include<cstdio>
 2 #include<cstring>
 3 #define mod(x,y) (((x)%(y)+(y))%(y))
 4 #define ll long long
 5 ll exgcd(ll a,ll b,ll &x,ll &y){
 6     if(b==0){
 7         x=1; y=0;
 8         return a;
 9     }
10     ll d=exgcd(b,a%b,x,y);
11     ll t=y;
12     y=x-a/b*y;
13     x=t;
14     return d;
15 }
16 ll MLES(ll a,ll b,ll n){
17     ll x,y;
18     ll d=exgcd(a,n,x,y);
19     if(b%d) return -1;
20     return mod(x*(b/d),n/d);
21 }
22 int main(){
23     ll a,b,c,k;
24     while(~scanf("%lld%lld%lld%lld",&a,&b,&c,&k) && (a||b||c||k)){
25         k=1LL<<k;
26         ll res=MLES(c,b-a,k);
27         if(res==-1) puts("FOREVER");
28         else printf("%lld\n",res);
29     }
30     return 0;
31 }
时间: 2024-08-01 22:43:18

POJ2115 C Looooops(线性同余方程)的相关文章

POJ 2115 C Looooops (线性同余方程)

C Looooops Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19141   Accepted: 5049 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 w

POJ2115 C Looooops【解线性同余方程】

题目链接: http://poj.org/problem?id=2115 题目大意: 对于循环语句: for(int i = A; i != B; i += C) 语句1: 已知i.A.B.C都是k进制的无符号整数类型,给出A.B.C.k的值,计算并输出语句1 的执行次数,如果为无限次,那么直接输出"FOREVER". 思路: 设算法执行X步,那么题目就变为求解A + CX ≡ B( mod M)(M= 2^k).即A + CX + MY ≡ B. CX + MY ≡ B - A(M

POJ 2115C Looooops[一元线性同余方程]

一元线性同余方程 定义: $a$,$b$是整数,$m$是正整数,形如 $ax\equiv b\,(mod\, m)$ 且$x$是未知数的同余式称作一元线性同余方程. 对于方程$ax\equiv b\,(mod\, m)$, 可以把它写成二元一次不定式$ax+my=b$.要想方程有解,必须满足$(a,m)\mid d$. 这时利用扩展欧几里得求出$ax+my=(a,m)$ 的一个特解,在乘上$b/(a,m)$就是我们所要的一个特解. 利用公式: $ax_0+my_0=d=ax+my\Rightar

POJ 2115 C Looooops (扩展欧几里德 + 线性同余方程)

分析:这个题主要考察的是对线性同余方程的理解,根据题目中给出的a,b,c,d,不难的出这样的式子,(a+k*c) % (1<<d) = b; 题目要求我们在有解的情况下求出最小的解,我们转化一下形式. 上式可以用同余方程表示为  a + k*c = (b) % (1<<d)   <-->  k*c = (b-a) % (1<<d)(中间应该是全等号,打不出来…).这就是我们想要的同余方程,根据我的个人习惯,我把它转化为线性方程的形式. -->   c*

POJ 1061 - 青蛙的约会 - [exgcd求解一元线性同余方程]

先上干货: 定理1: 如果d = gcd(a,b),则必能找到正的或负的整数k和l,使ax + by = d. (参考exgcd:http://www.cnblogs.com/dilthey/p/6804137.html) 定理2: 一元线性同余方程ax ≡ n (mod b) 有解,当且仅当gcd(a,b)|n. 也就是说,解出了ax+by=gcd(a,b),就相当于解出了ax≡n(mod b) (而且只要满足gcd(a,b)|n,就一定有解) 定理3: 若gcd(a,b) = 1,则方程ax

codeforces 710D Two Arithmetic Progressions(线性同余方程)

题目链接: http://codeforces.com/problemset/problem/710/D 分析:给你两个方程 a1k + b1 and a2l + b2,求在一个闭区间[L,R]中有多少个X,X满足 x = a1k' + b1 = a2l' + b2. 由此可以发现这两个方程满足线性同余,即 x ≡b1mod(a1) 且 x≡b2mod(a2); 也就是 a1k' + b1 = a2l' + b2a. 所以 a1k1 + (-a2k2) = (b2 - b1),由同余方程得 :

poj3708(公式化简+大数进制装换+线性同余方程组)

刚看到这个题目,有点被吓到,毕竟自己这么弱. 分析了很久,然后发现m,k都可以唯一的用d进制表示.也就是用一个ai,和很多个bi唯一构成. 这点就是解题的关键了. 之后可以发现每次调用函数f(x),相当于a(ai),b(bi)了一下.这样根据置换的一定知识,一定会出现循环,而把循环的大小看成取模,把从m->k的看成余,于是可以建立一个线性同余方程. 直接用模板解决之.. Recurrent Function Time Limit: 1000MS   Memory Limit: 65536K To

数论 - n元线性同余方程的解法

note:n元线性同余方程因其编程的特殊性,一般在acm中用的很少,这里只是出于兴趣学了一下 n元线性同余方程的概念: 形如:(a1*x1+a2*x2+....+an*xn)%m=b%m           ..................(1) 当然也有很多变形,例如:a1*x1+a2*x2+...+an*xn+m*x(n+1)=b.这两个都是等价的. 判断是否有解: 解线性同余方程,我们首先要来判断方程是否有解,方程有解的充要条件是:d%b==0.其中d=gcd(a1,a2,...an)

求解一元线性同余方程组模版

解法:直接上模版. 扩展欧几里德的模版: typedef long long LL; LL ex_gcd(LL a,LL b,LL &x,LL &y) { if(b==0) { x=1; y=0; return a; } LL d=ex_gcd(b,a%b,x,y); LL t=x; x=y; y=t-a/b*y; return d; } 求解一元线性同余方程组模版: LL solve(LL n) { LL a1,r1,a2,r2; LL a,b,c,r,x,y; bool ifhave=