转载:http://www.klogk.com/posts/hdu4565/

这里写的很好,看看就知道了啊。

题意非常简单, a,b,n 都是正整数,求

Sn=(a+b)n%m,(a1)2<b<a2

这个题目也是2008年Google Codejam Round 1A的C题

做法其实非常简单,记 (a+b)n An ,配项

Cn=An+Bn=(a+b)n+(ab)n

两项恰好共轭,所以 Cn 是整数。又根据限制条件

(a1)2<b<a20<ab<10<(ab)n<1Bn<1

也就是说 Cn=An

Sn=(Cn)%m

Cn 的方法是递推。 对 Cn 乘以 (a+b)+(ab)

Cn[(a+b)+(ab)]=[(a+b)n+(ab)n][(a+b)+(ab)]=(a+b)n+1+(ab)n+1+(a+b)n(ab)+(ab)n(a+b)=Cn+1+(a2b)(a+b)n1+(a2b)(ab)n1=Cn+1+(a2b)Cn1

于是

Cn+1=2aCn(a2b)Cn1

把这个递推式写成矩阵形式

[Cn+1Cn]=[2a1(a2b)0][CnCn1]

于是就可以用矩阵快速幂来做了

[Cn+1Cn]=[2a1(a2b)0]n[C1C0]

So Easy!

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2286    Accepted Submission(s): 710


Problem Description
  A sequence S n is defined as:

Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate S n.
  You, a top coder, say: So easy! 
 

Input
  There are several test cases, each test case in one line contains four positive integers: a, b, n, m. Where 0< a, m < 2 15, (a-1) 2< b < a 2, 0 < b, n < 2 31.The input will finish with the end of file.
 

Output
  For each the case, output an integer S n.
 

Sample Input
   
2 3 1 2013 2 3 2 2013 2 2 1 2013
 

Sample Output
   
4 14 4
 

<span style="font-size:18px;">#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-10
///#define M 1000100
#define LL __int64
///#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)

///#define mod 10007

const int maxn = 210;

using namespace std;

struct matrix
{
    LL f[3][3];
};
LL mod;

matrix mul(matrix a, matrix b, int n)
{
    matrix c;
    memset(c.f, 0, sizeof(c.f));
    for(int k = 0;k < n; k++)
    {
        for(int i = 0; i < n;i++)
        {
            if(!a.f[i][k]) continue;
            for(int j = 0; j < n; j++)
            {
                if(!b.f[k][j]) continue;
                c.f[i][j]=(c.f[i][j]+a.f[i][k]*b.f[k][j]+mod)%mod;
            }
        }
    }
    return c;
}
matrix pow_mod(matrix a, LL b, int n)
{
    matrix s;
    memset(s.f, 0 , sizeof(s.f));
    for(int i = 0; i < n; i++) s.f[i][i] = 1LL;
    while(b)
    {
        if(b&1) s = mul(s, a, n);
        a = mul(a, a, n);
        b >>= 1;
    }
    return s;
}

int main()
{
    LL a, b, n;
    while(~scanf("%I64d %I64d %I64d %I64d",&a, &b, &n, &mod))
    {
        if(n == 1)
        {
            printf("%I64d\n",2*a%mod);
            continue;
        }
        matrix c;
        memset(c.f, 0 , sizeof(c.f));
        c.f[0][0] = 2LL*a;
        c.f[0][1] = b-a*a;
        c.f[1][0] = 1LL;
        matrix d = pow_mod(c, n-1, 2);
        printf("%I64d\n",((d.f[0][0]*2*a+d.f[0][1]*2)%mod+mod)%mod);
    }
    return 0;
}</span>