poj 2115 C Looooops(推公式+扩展欧几里得模板)
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
Source
解题思路:这道题和POJ1061(青蛙约会)一样,都是同余方程的求解,用到了拓展欧几里德算法。而本题题意明确,就是求解这个公式:(a+c*x)mod2^k=b ,求得x 的最小解。变形后可得:c*xmod2^k=b-a,即 c*x=(b-a)mod2^k; 这就是标准的同余方程。
注意:k <=32 ,而 2的 32次方超出整数范围,所以要用__int64或long long ,就不会出现runtime error了。

1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<math.h> 7 #include<algorithm> 8 #include<queue> 9 #include<set> 10 #include<bitset> 11 #include<map> 12 #include<vector> 13 #include<stdlib.h> 14 using namespace std; 15 #define max(a,b) (a) > (b) ? (a) : (b) 16 #define min(a,b) (a) < (b) ? (a) : (b) 17 #define ll long long 18 #define eps 1e-10 19 #define MOD 1000000007 20 #define N 1000000 21 #define inf 1e12 22 ll fac(ll m){ 23 ll ans=2; 24 for(ll i=1;i<m;i++){ 25 ans=ans*2; 26 } 27 return ans; 28 } 29 ll e_gcd(ll a,ll b,ll &x,ll &y){ 30 if(b==0) 31 { 32 x=1; 33 y=0; 34 return a; 35 } 36 ll r=e_gcd(b,a%b,x,y); 37 ll t=x; 38 x=y; 39 y=t-a/b*y; 40 return r; 41 } 42 int main() 43 { 44 ll a,b,c,k; 45 while(scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&k)==4){ 46 if(a==0 && b==0 && c==0 && k==0){ 47 break; 48 } 49 ll x,y,r; 50 ll d=e_gcd(c,fac(k),x,y); 51 //printf("---%I64d %I64d %I64d\n",d,x,y); 52 if((b-a)%d!=0){ 53 printf("FOREVER\n"); 54 } 55 else{ 56 x=x*(b-a)/d; 57 r=fac(k)/d; 58 x=(x%r+r)%r; 59 printf("%I64d\n",x); 60 } 61 } 62 return 0; 63 }
分类:
ACM---《挑战程序设计》
, ACM---数学、思维
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架