您的位置:首页 > 其它

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

2014-04-01 19:09 351 查看

Partition

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


[align=left]Problem Description[/align]
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.

[align=left]Input[/align]
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).

[align=left]Output[/align]
Output the required answer modulo 109+7 for each test case, one per line.

[align=left]Sample Input[/align]

2

4 2

5 5

[align=left]Sample Output[/align]

5
1

[align=left]Source[/align]
2013 Multi-University Training Contest 1

递推公式: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\n");continue;}
n=n-k+1;
if(n==1) {printf("1\n");continue;}
if(n==2) {printf("2\n");continue;}
if(n==3) {printf("5\n");continue;}
printf("%I64d\n",deal(n-3));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: