hdu 4602 递推关系矩阵快速幂模

Partition

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


Problem Description
Define f(n) as the number of ways to perform n in format of the sum of some positive integers. For instance, when n=4, we have
  4=1+1+1+1
  4=1+1+2
  4=1+2+1
  4=2+1+1
  4=1+3
  4=2+2
  4=3+1
  4=4
totally 8 ways. Actually, we will have f(n)=2(n-1) after observations.
Given a pair of integers n and k, your task is to figure out how many times that the integer k occurs in such 2(n-1) ways. In the example above, number 1 occurs for 12 times, while number 4 only occurs once.
 
Input
The first line contains a single integer T(1≤T≤10000), indicating the number of test cases.
Each test case contains two integers n and k(1≤n,k≤109).
 
Output
Output the required answer modulo 109+7 for each test case, one per line.
 
Sample Input
2
4 2
5 5
 
Sample Output
5
1
 
Source
 

 递推公式:f(n)=4*f(n-1)-4*f(n-2)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

typedef __int64 LL;
const int Mod=1000000007;

struct Matrix
{
    LL a[3][3];
};

Matrix mult_mod(Matrix A,Matrix B)
{
    int i,j,k;
    Matrix C;
    for(i=1;i<=2;i++)
    {
        for(j=1;j<=2;j++)
        {
            C.a[i][j]=0;
            for(k=1;k<=2;k++)
            {
                C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j]%Mod+Mod)%Mod;
            }
        }
    }
    return C;
}

Matrix Matrix_pow_mod(Matrix A,int n)
{
    struct Matrix ret;
    ret.a[1][1]=ret.a[2][2]=1;
    ret.a[1][2]=ret.a[2][1]=0;
    while(n)
    {
        if(n&1) ret=mult_mod(ret,A);
        A=mult_mod(A,A);
        n>>=1;
    }
    return ret;
}

LL deal(int n)
{
    struct Matrix A;
    A.a[1][1]=4;A.a[1][2]=-4;A.a[2][1]=1;A.a[2][2]=0;
    A=Matrix_pow_mod(A,n);
    return (A.a[1][1]*5%Mod+A.a[1][2]*2%Mod)%Mod;
}

int main()
{
    int t,n,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&k);
        if(k > n) {printf("0
");continue;}
        n=n-k+1;
        if(n==1) {printf("1
");continue;}
        if(n==2) {printf("2
");continue;}
        if(n==3) {printf("5
");continue;}
        printf("%I64d
",deal(n-3));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xiong-/p/3639017.html