A Boring Question
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 60 Accepted Submission(s): 19
Problem Description
There are an equation.
∑
0≤k
1
,k
2
,⋯k
m
≤n
∏
1⩽j<m
(k
j+1![]()
k
j![]()
)%1000000007=?
We define that (k
j+1![]()
k
j![]()
)=k
j+1
!
k
j
!(k
j+1
−k
j
)!![]()
![]()
. And
(k
j+1![]()
k
j![]()
)=0
while
k
j+1
<k
j![]()
.
You have to get the answer for each n
and
m
that given to you.
For example,if n=1
,
m=3
,
When k
1
=0,k
2
=0,k
3
=0,(k
2![]()
k
1![]()
)(k
3![]()
k
2![]()
)=1
;
When k
1
=0,k
2
=1,k
3
=0,(k
2![]()
k
1![]()
)(k
3![]()
k
2![]()
)=0
;
When k
1
=1,k
2
=0,k
3
=0,(k
2![]()
k
1![]()
)(k
3![]()
k
2![]()
)=0
;
When k
1
=1,k
2
=1,k
3
=0,(k
2![]()
k
1![]()
)(k
3![]()
k
2![]()
)=0
;
When k
1
=0,k
2
=0,k
3
=1,(k
2![]()
k
1![]()
)(k
3![]()
k
2![]()
)=1
;
When k
1
=0,k
2
=1,k
3
=1,(k
2![]()
k
1![]()
)(k
3![]()
k
2![]()
)=1
;
When k
1
=1,k
2
=0,k
3
=1,(k
2![]()
k
1![]()
)(k
3![]()
k
2![]()
)=0
;
When k
1
=1,k
2
=1,k
3
=1,(k
2![]()
k
1![]()
)(k
3![]()
k
2![]()
)=1
.
So the answer is 4.
∑
We define that (k
You have to get the answer for each n
For example,if n=1
When k
When k
When k
When k
When k
When k
When k
When k
So the answer is 4.
Input
The first line of the input contains the only integer
T
,
(1≤T≤10000)
Then T
lines follow,the i-th line contains two integers
n
,
m
,
(0≤n≤10
9
,2≤m≤10
9
)
Then T
Output
For each
n
and
m
,output the answer in a single line.
Sample Input
2 1 2 2 3
Sample Output
3 13
关键在于递推公式的推导,真是想了太久 Ai=Ai-1(m)+1;
剩下的就是裸的矩阵幂了。。
#include <cstdio>
#define inf 1000000007
long long n,ms;
const int MAX = 2;
struct node
{
long long m[MAX][MAX];
}Str,A;
node matrixmul(node a,node b)
{
node c;
for(int i=0;i<MAX;i++)
for(int j=0;j<MAX;j++)
c.m[i][j]=0;
int i,j,k;
for (i = 0 ; i < MAX; i++)
for (j = 0; j < MAX;j++)
{
for (k = 0; k < MAX; k++)
c.m[i][j] += (a.m[i][k]%inf * b.m[k][j]%inf)%inf;
c.m[i][j] %= inf;
}
return c;
}
node quickpow(long long n)
{
node m = A, b = Str;
node c;
for(int i=0;i<MAX;i++)
for(int j=0;j<MAX;j++)
{
if(i==j)
c.m[i][j]=1;
else
c.m[i][j]=0;
}
while (n >= 1)
{
if(n&1)
c=matrixmul(c,b);
b = matrixmul(b,b);
n = n /2;
}
return c;
}
int main()
{
node re;
int T;
scanf("%d",&T);
while (T--)
{
A.m[0][0]=1;
A.m[0][1]=1;
A.m[1][0]=0;
A.m[1][1]=0;
scanf("%lld%lld",&n,&ms);
Str.m[0][0]=ms;
Str.m[0][1]=0;
Str.m[1][0]=1;
Str.m[1][1]=1;
re=quickpow(n);
long long t=(re.m[0][0]+re.m[1][0])%inf;
printf("%lld\n",t);
}
}