您的位置:首页 > 其它

srm#397_div1_500pt 矩阵乘法+快速模幂

2014-03-16 20:17 351 查看
题目地址:srm#397_div1_500

题目描述:

Problem Statement

NOTE: This problem statement contains superscripts that may not display properly if viewed outside of the applet.

You are given ints n and k. Return the value of the sum 1k + 2k + 3k + ... +
nk modulo 1000000007.

Definition

Class:SumOfPowers
Method:value
Parameters:int, int
Returns:int
Method signature:int value(int n, int k)
(be sure your method is public)

Limits

Time limit (s):2.000
Memory limit (MB):64

Constraints

-n will be between 1 and 109, inclusive.
-k will be between 1 and 50, inclusive.

Examples

0)
5

1

Returns: 15

Here, we have arithmethic progression: 1 + 2 + 3 + 4 + 5 = 15.
1)
4

2

Returns: 30

Just a little bit more complicated example here: 12 + 22 + 32 + 42 = 1 + 4 + 9 + 16 = 30.
2)
13

5

Returns: 1002001

This one would be harder to check by hand.
3)
123456789

1

Returns: 383478132

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.

构造一个k+2阶矩阵;

这里n比较大 显然我们接受不了O(n)的复杂度

最好的方法就是像求Fibonacci数列第n项一样用矩阵乘法+快速幂做

要实现求和长度在k左右的递推式

首选(n+1)^k-n^k=sigma(c[k][i]*n^i);

直接看代码里面的矩阵构造吧

wa了几次

1 组合数是要求到c[52][i]的

2 因为mod 10^9+7 所以存在的数都是可能接近int上限的 要进行+运算 所以要用long long 存储

代码:

#include<iostream>

typedef  long long inta ;

using namespace std;

struct Matrix
{
inta  m[60][60];

};

inta n;    //  用来表示维度

inta   c[60][60];    //组合数

const   inta  mod=1000000007;

void init()
{
for(inta i=0;i<=55;i++)
c[i][0]=1;

for(inta i=0;i<55;i++)
for(inta j=0;j<=i;j++)
c[i+1][j+1]=c[i][j+1]+c[i][j];

}

Matrix multi(Matrix a,Matrix b)
{

Matrix ans;

for(inta i=0;i<n;i++)
for(inta j=0;j<n;j++)
{
inta   c=0;
for(inta k=0;k<n;k++)
c=(c+a.m[i][k]*b.m[k][j])%mod;

ans.m[i][j]=c;

}

return ans;

}

Matrix quick_mod(Matrix a,inta b)
{
Matrix  ans;

Matrix  p=a;

for(inta i=0;i<n;i++)
for(inta j=0;j<n;j++)
ans.m[i][j]=(i==j?1:0);

while(b)
{
if(b&1)
{
ans=multi(ans, p);
b--;
}

b>>=1;
p=multi(p, p);

}

return ans;

}

class  SumOfPowers
{
public :
inta value(inta nn,inta k)
{
init();
n=k+2;

Matrix   A;

for(inta i=0;i<n;i++)      //  so  important
for(inta j=0;j<n;j++)
A.m[i][j]=0;

for(inta i=0;i<k+1;i++)
for(inta j=0;j<=i;j++)
A.m[i][j]=c[i][j]%mod;

for(inta i=0;i<k+1;i++)
A.m[k+1][i]=c[k][i]%mod;

A.m[k+1][k+1]=1;

A=quick_mod(A, nn-1);

inta   ans=0;
for(inta i=0;i<k+2;i++)
ans=(ans+A.m[k+1][i])%mod;

return ans;
}
};

int  main()
{

inta  nn,k;
cin>>nn>>k;

SumOfPowers  obj;

cout<<obj.value(nn, k)<<endl;

}


tc上提交没有main()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: