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

2019-04-14 12:46发布

题目地址: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 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>=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>nn>>k; SumOfPowers obj; cout<
tc上提交没有main()