HDU 5451 数论
来源:互联网 发布:游族网络2018校园招聘 编辑:程序博客网 时间:2024/06/03 15:42
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5451
本题与HDU 4565类似,构造一个类似fibo的递推式,然后用矩阵快速幂求得需要的那一项,由于此题幂次比较高,我们可以通过寻找循环节——(mod + 1) * (mod - 1)来实现降幂。
据出题人的意思来说,还有一个较大的循环节推法,(p2−p)(p2−1),这个表示为Zp下矩阵形成的群的大小,也是因此出题人选择了限定了p的大小,
使得循环节不超过LL。
构造fibo递推式的部分,具体解释参见:http://blog.csdn.net/acdreamers/article/details/8994222
AC代码:
//做法类似HDU 4565#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <vector>#include <limits.h>#include <queue>#include <map>#include <set>using namespace std;typedef long long LL;#define pll pair<LL, LL>#define pii pair<int, int>#define X first#define Y second#define MAXN 1000010//1e6#define lson l, mid, (rt << 1)#define rson mid + 1, r, (rt << 1 | 1)#define N 3int K;LL mod;const LL a = 5, b = 24;struct Matrix { int r, c; LL m[N][N]; Matrix() {} Matrix(int r,int c) : r(r), c(c) {} Matrix operator *(const Matrix& B) { Matrix T(r, B.c); for(int i = 1; i <= T.r; i++) { for(int j = 1; j <= T.c; j++) { LL tt = 0; for(int k=1; k <= c; k++) tt += m[i][k] * B.m[k][j] % mod; T.m[i][j] = tt % mod; } } return T; } Matrix Unit(int h) { Matrix T(h, h); memset(T.m, 0, sizeof(T.m)); for(int i = 1; i <= h; i++) T.m[i][i] = 1; return T; } Matrix Pow(LL n) { Matrix P = *this, Res = Unit(r); while(n) { if(n & 1) Res = Res * P; P = P * P; n >>= 1; } return Res; }} Single;Matrix p, ans;LL power(LL a, LL b, LL MOD) { LL res = 1LL; a %= MOD; while(b) { if(b & 1) { res = res * a % MOD; b--; } b >>= 1LL; a = a * a % MOD; } return res;}void init() { p = Matrix(2,2), ans = Matrix(2, 1); // 初始矩阵 ans.m[1][1] = (b + a * a % mod) % mod * 2 % mod; ans.m[2][1] = 2 * a %mod; // 操作矩阵 p.m[1][1] = ans.m[2][1]; p.m[1][2] = (b - a * a % mod + mod) % mod; p.m[2][1] = 1; p.m[2][2] = 0;}int main() { LL n, x; int T, cas = 0; scanf("%d", &T); while(T--) { cin >> x >> mod; LL MOD = (mod + 1) * (mod - 1); n = power(2, x, MOD); n = (n + 1) % MOD; if(n == 1) { cout << (2 * a - 1 + mod) % mod << endl; continue; } init(); ans = p.Pow(n - 2) * ans; printf("Case #%d: ", ++cas); cout << (ans.m[1][1] - 1 + mod) % mod << endl; } return 0;}
0 0
- HDU 5451 数论
- HDU 2204 (数论)
- 数论 MillerRabin hdu 3792
- HDU 3123 数论
- 【数论】HDU-4196-Remoteland
- HDU 3988 数论
- HDU 1787 数论
- hdu 1395 数论
- HDU 2104数论 欧几里得
- HDU 1060 数论
- HDU 2161 Primes 数论
- HDU 1695 GCD 数论
- HDU 1568 Fibonacci 数论
- hdu 4542 数论
- hdu 1722(数论)
- hdu 1492(数论)
- hdu 2554 (数论)
- hdu 2964 (数论)
- 约瑟夫环的问题
- Matlab高效谱聚类(推荐)
- An easy problem 2601 (数学题+公式变形)
- nyoj 349 Sorting It All Out(拓扑排序度的理解)
- 软件测试方法分类
- HDU 5451 数论
- Unity热更新专题(八)uLua示例Demo简析及SimpleFramework工作流程
- Unity3d NGUI伪自适应
- ViewGroup自定义布局(左上右下)
- UILabel标签
- android之动画(透明度,位移,旋转,缩放)
- Java面向对象 修饰符
- 隐马尔科夫模型——简介
- 侦查