[HDOJ5667]Sequence(矩阵快速幂,费马小定理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5667

费马小定理:

假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p)。

即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。

注意这里使用快速幂的时候要根据费马小定理对p-1取模。还有注意a%p=0的情况。

递推式:f(n)=f(n-1)*c+f(n-2)+1 非齐次。

构造矩阵:

|c 1 1|
|1 0 0|
|0 0 1|

初始的矩阵:

|1|
|0|
|1|
  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19
 20 using namespace std;
 21
 22 typedef long long ll;
 23 const ll maxn = 10;
 24 ll n, a, b, c, p;
 25
 26 typedef struct Matrix {
 27     ll m[maxn][maxn];
 28     ll r;
 29     ll c;
 30     Matrix(){
 31         r = c = 0;
 32         memset(m, 0, sizeof(m));
 33     }
 34 } Matrix;
 35
 36 Matrix mul(Matrix m1, Matrix m2, ll mod) {
 37     Matrix ans = Matrix();
 38     ans.r = m1.r;
 39     ans.c = m2.c;
 40     for(ll i = 1; i <= m1.r; i++) {
 41         for(ll j = 1; j <= m2.r; j++) {
 42                for(ll k = 1; k <= m2.c; k++) {
 43                 if(m2.m[j][k] == 0) continue;
 44                 ans.m[i][k] = ((ans.m[i][k] + m1.m[i][j] * m2.m[j][k] % mod) % mod) % mod;
 45             }
 46         }
 47     }
 48     return ans;
 49 }
 50
 51 Matrix quickmul(Matrix m, ll n, ll mod) {
 52     Matrix ans = Matrix();
 53     for(ll i = 1; i <= m.r; i++) {
 54         ans.m[i][i]  = 1;
 55     }
 56     ans.r = m.r;
 57     ans.c = m.c;
 58     while(n) {
 59         if(n & 1) {
 60             ans = mul(m, ans, mod);
 61         }
 62         m = mul(m, m, mod);
 63         n >>= 1;
 64     }
 65     return ans;
 66 }
 67
 68 ll qm(ll x, ll n, ll mod) {
 69     ll ans = 1, t = x;
 70     while(n) {
 71         if(n & 1) ans = (ans * t) % mod;
 72         t = (t * t) % mod;
 73         n >>= 1;
 74     }
 75     return ans;
 76 }
 77 int main() {
 78     // freopen("in", "r", stdin);
 79     int T;
 80     scanf("%d", &T);
 81     while(T--) {
 82         cin >> n >> a >> b >> c >> p;
 83         Matrix r;
 84         r.r = 3, r.c = 1;
 85         r.m[1][1] = 1;
 86         r.m[2][1] = 0;
 87         r.m[3][1] = 1;
 88         if(n == 1) {
 89             printf("1\n");
 90             continue;
 91         }
 92         if(n == 2) {
 93             printf("%I64d\n", qm(a, b, p));
 94             continue;
 95         }
 96         if(a % p == 0) {
 97             printf("0\n");
 98             continue;
 99         }
100         Matrix s;
101         s.r = s.c = 3;
102         s.m[1][1] = c, s.m[1][2] = 1, s.m[1][3] = 1;
103         s.m[2][1] = 1, s.m[2][2] = 0, s.m[2][3] = 0;
104         s.m[3][1] = 0, s.m[3][2] = 0, s.m[3][3] = 1;
105         s = quickmul(s, n-2, p-1);
106         ll ans = 0;
107         for(int i = 1; i <= r.r; i++) {
108             ans = (ans + (s.m[1][i] * r.m[i][1]) % (p - 1)) % (p - 1);
109         }
110         printf("%I64d\n", qm(a, (ans*b)%(p-1), p));
111     }
112     return 0;
113 }
时间: 2024-12-13 21:15:59

[HDOJ5667]Sequence(矩阵快速幂,费马小定理)的相关文章

hdu-5667 Sequence(矩阵快速幂+费马小定理+快速幂)

题目链接: Sequence Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Problem Description Holion August will eat every thing he has found. Now there are many foods,but he does not want to eat all of them at once,so he fi

HDU 5667 Sequence(矩阵快速幂+费马小定理)

题意:不好复制,直接上链接http://acm.hdu.edu.cn/showproblem.php?pid=5667 思路: 观察递推式我们可以发现,所有的f_if?i??都是aa的幂次,所以我们可以对f_if?i??取一个以aa为底的loglog,即g_i=log_a\ f_ig?i??=log?a?? f?i?? 那么递推式变成g_i=b+c*g_{i-1}+g_{i-2}g?i??=b+c∗g?i−1??+g?i−2??,这个式子可以矩阵乘法 这题有一个小trick,注意a\ mod\

HDU 4549 M斐波那契数列 ( 矩阵快速幂 + 费马小定理 )

HDU 4549 M斐波那契数列 (  矩阵快速幂 + 费马小定理  ) 题意:中文题,不解释 分析:最好的分析就是先推一推前几项,看看有什么规律 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef __int64 LL; #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 100000

hdu 4549 (矩阵快速幂+费马小定理)

题意:已知F0=a,F1=b,Fn=Fn-1*Fn-2,给你a,b,n求Fn%1000000007的值 思路:我们试着写几组数 F0=a F1=b F2=a*b F3=a*b2 F4=a2*b3 F5=a3*b5 我们发现a,b的系数其实是斐波那契数列,我们只需用矩阵快速幂求出相应系数就行,但是 这个系数随着增长会特别大,这时我们需要利用费马小定理进行降幂处理 费马小定理 ap-1≡1(mod p) 代码: #include <iostream> #include <cmath>

hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4549: 题目是中文的很容易理解吧.可一开始我把题目看错了,这毛病哈哈. 一开始我看错题时,就用了一个快速幂来解,不用说肯定wa,看题目的通过率也不高,我想会不会有啥坑啊.然而我就是那大坑,哈哈. 不说了,直接说题吧,先讨论k=1,2,3;时的解.这应该会解吧,不多说了: 从第四项开始f(4)=a^1+b^2;f(5)=a^2+b^3;f(6)=a^3+b^5......; 看出来了吧,a上的指数成斐波

HDU 4549 M斐波那契数列(矩阵快速幂&amp;费马小定理)

ps:今天和战友聊到矩阵快速幂,想到前几天学长推荐去刷矩阵专题,挑了其中唯一一道中文题,没想到越过山却被河挡住去路... 题目链接:[kuangbin带你飞]专题十九 矩阵 R - M斐波那契数列 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u 题意 Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2]

CSU1516矩阵快速幂+费马小定理

通过这个题真的学到了不少东西,最起码矩阵快速幂算是入门了,普通快速幂也彻底明白了(以前都是打模板),了解了费马小定理 关键点 求(a^fib[b])%p 的值其中p是素数,0<a<p, b在int范围内 先假设fib[b]>p-1 那么上式 (a^fib[b])%p = (a^(p-1)*a^(p-1)*....*a^(p-1)*a^m)%p (这里 m = fib[b]%(p-1)) 由于p是素数且a<p那么gcd(a,p)=1,所以由费小可得(a^(p-1))%p=1 那上式就

M斐波那契数列(矩阵快速幂+费马小定理)

M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1672    Accepted Submission(s): 482 Problem Description M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a,

hdu 4549 M斐波拉契 (矩阵快速幂 + 费马小定理)

Problem DescriptionM斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的值吗? Input输入包含多组测试数据:每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 ) Output对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,

hdu4549矩阵快速幂+费马小定理

转移矩阵很容易求就是|0  1|,第一项是|0| |1  1|             |1| 然后直接矩阵快速幂,要用到费马小定理 :假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p).即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1(这东西贡献了我8次wa) 对矩阵进行取余的时候余mod-1,因为矩阵求出来是要当作幂的,就是a^b%p=a^(b%(p-1))%p #include<map> #includ