hdoj 5451 Best Solver 【求循环节 + 矩阵快速幂】
2015-09-20 01:29
405 查看
Best SolverTime Limit: 1500/1000 MS (Java/Others) Memory Limit: 65535/102400 K (Java/Others)Total Submission(s): 229 Accepted Submission(s): 98 Problem Description The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart. It is known that y=(5+26√)1+2x. For a given integer x (0≤x<232) and a given prime number M (M≤46337), print [y]%M. ([y] means the integer part of y) Input An integer T (1<T≤1000), indicating there are T test cases. Following are T lines, each containing two integers x and M, as introduced above. Output The output contains exactly T lines. Each line contains an integer representing [y]%M. Sample Input 7 0 46337 1 46337 3 46337 1 46337 21 46337 321 46337 4321 46337 Sample Output Case #1: 97 Case #2: 969 Case #3: 16537 Case #4: 969 Case #5: 40453 Case #6: 10211 Case #7: 17947 |
打表找出循环节loop = (M - 1) * (M + 1),然后求解 2^n % loop,下面就是矩阵快速幂裸题了。
提交6次代码才过,CE5次。杭电要炸了。。。
找循环节解析链接:点我
裸题链接:点我
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #define LL long long struct Matrix { LL a[3][3]; }; Matrix ori, res; LL M; void init() { memset(ori.a, 0, sizeof(ori.a)); memset(res.a, 0, sizeof(res.a)); for(int i = 0; i < 2; i++) res.a[i][i] = 1; ori.a[0][0] = 5, ori.a[0][1] = 2; ori.a[1][0] = 12, ori.a[1][1] = 5; } Matrix muitl(Matrix x, Matrix y) { Matrix z; memset(z.a, 0, sizeof(z.a)); for(int i = 0; i < 2; i++) { for(int k = 0; k < 2; k++) { if(x.a[i][k] == 0) continue; for(int j = 0; j < 2; j++) z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j]) % M) % M; } } return z; } LL F[3], ans[3]; int k = 1; void solve(LL n) { while(n) { if(n & 1) res = muitl(ori, res); ori = muitl(ori, ori); n >>= 1; } for(int i = 0; i < 2; i++) { ans[i] = 0; for(int k = 0; k < 2; k++) ans[i] = (ans[i] + (F[k] * res.a[k][i]) % M) % M; } printf("Case #%d: %lld\n", k++, (2*ans[0] - 1) % M); } LL pow_mod(LL a, LL p, LL n) { if(p == 0) return 1; LL ans = pow_mod(a, p/2, n); ans = ans * ans % n; if(p % 2 == 1) ans = ans * a % n; return ans; } int main() { int t; LL n, N; F[0] = 5, F[1] = 2; scanf("%d", &t); while(t--) { scanf("%lld%lld", &n, &M); LL loop = (M+1) * (M-1);//循环节 LL N = pow_mod(2, n, loop) + 1;//快速幂 求解2^n % loop init();//构造矩阵 solve(N-1);//矩阵快速幂 } return 0; }
相关文章推荐
- 对Extjs中store的多种操作
- 潘鹏整理WPF(2)轻量级文本因Size小模糊解决
- java多态的理解
- HTML5 应用缓存使用心得
- poj1755Triathlon【半平面交】
- 嘣嘣嘣嘣嘣哥TnT
- 对git的认识
- Map与List和Vector性能比较
- javascript函数的3种定义方式
- 深入理解Android View(1)
- 对git的认识
- C/C++、Java、Python谁是编译型语言,谁是解释型语言?
- 封装自己的ajax工具包
- c++编译中出现‘vtable for ***未定义的引用解决办法
- Git
- python实现栈
- 升级到Ubuntu 14.04 报 "symbol 'grub_term_highlight_color' not found"错误的解决方法
- javaweb mysql实现分页功能
- Java SQL语句解析——Jsqlparser开源项目
- 高效通信模型之 - 异步通信模型