hdu 5451 Best Solver(矩阵乘法+数论)
2015-09-29 20:14
302 查看
题目链接:hdu 5451 Best Solver
解题思路
因为取模的数很小,所以暴力找打循环节,然后求解。代码
#include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <set> #include <algorithm> using namespace std; const int maxn = 46340; typedef int Mat[2][2]; struct State { int d, p; State (int d = 0, int p = 0): d(d), p(p) {} bool operator < (const State& u) const { return d < u.d; } }; int N, M; Mat X, Y; vector<State> G[maxn]; void mul(Mat a, Mat b, Mat& c) { Mat s; memset(s, 0, sizeof(s)); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) s[i][j] = (s[i][j] + a[i][k] * b[k][j] % M) % M; } } memcpy(c, s, sizeof(s)); } void init () { scanf("%d%d", &N, &M); X[0][0] = X[1][1] = 5 % M; X[1][0] = 2 % M, X[0][1] = 12 % M; memcpy(Y, X, sizeof(X)); for (int i = 0; i < M; i++) G[i].clear(); } int solve () { int start = 0, cnt = 1; while (!start) { int a = X[0][0], b = X[1][0]; State u = State(b, cnt); for (int i = 0; i < G[a].size(); i++) if (G[a][i].d == b) start = G[a][i].p; mul(X, X, X); G[a].push_back(u); cnt++; } cnt -= (start + 1); memcpy(X, Y, sizeof(Y)); for (int i = 0; i < min(start, N); i++) mul(X, X, X); if (N > start) { N -= start; N = N % cnt; for (int i = 0; i < N; i++) mul(X, X, X); } mul(X, Y, X); return (2 * X[0][0] - 1 + M) % M; } int main () { int cas; scanf("%d", &cas); for (int kcas = 1; kcas <= cas; kcas++) { init(); printf("Case #%d: %d\n", kcas, solve()); } return 0; }
相关文章推荐
- 导航地图1_地图显示
- Emacs中英文等宽字体设置
- 股票买卖(算法)
- C语言qsort函数算法性能测试
- Emacs中英文等宽字体设置
- 【转】做好软件测试需要具备的思维方式
- Java时间类型转换
- jquery自定义插件——window实现
- MINA2 源代码学习--源代码结构梳理
- 关于代码规范的个人观点及伙伴个人项目的代码复审
- RecycleView的使用总结
- 数字签名和数字证书技术简介(两)
- 谈加班文化
- 《看见》让我看到了另外一个世界
- linux lsof命令详解
- iOS大典之自定义cell
- 英语翻译之路-5-20150929 Our planet is home to about seven billion people. 我们的地球大约七十亿人口。(我们的地球是七十亿人口所在地)
- 调试wow64进程
- CF581B Luxurious Houses
- LINUX基础指令