题目大意:
给出 N,k, 1 <= N <= 10^15, 0 <= k <= 50;
求( 1^k + 2^k + ... + N^k) mod (2^32) 的值
大致思路:
是个很明显的矩阵快速幂的题吧, 之前学长推荐过这道题,现在居然正好碰到了
不过刚开始一直因为 %lld 和 %I64d 的原因WA了3次..以后还是要注意OJ上的FAQ的问题...
设S(n) = sigma(i^k) mod (2^32) i 从1到n
这道题的关键就是发现这样的转换关系:
这样转换矩阵当中的数之和K有关,这样就好办了
直接用快速幂,最后得到的S(n)就是答案
代码如下:
Result : Accepted Memory : 1716 KB Time : 1724 ms
/*
* Author: Gatevin
* Created Time: 2014/7/29 18:29:03
* File Name: test.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
lint k,siz;
lint n;
const lint mod = ((long long)1 << 32);
lint C[60][60];
struct Matrix
{
lint a[53][53];
Matrix()
{
memset(a, 0, sizeof(a));
for(int i = 1; i <= 52; i++)
{
a[i][i] = 1LL;
}
}
};
Matrix operator * (const Matrix & m1, const Matrix & m2)
{
Matrix m;
for(int i = 1; i <= siz; i++)
{
for(int j = 1; j <= siz; j++)
{
m.a[i][j] = 0;
for(int k = 1; k <= siz; k++)
{
m.a[i][j] = (m.a[i][j] + (m1.a[i][k] * m2.a[k][j]) % mod) % mod;
}
}
}
return m;
}
Matrix quick_pow(Matrix base, lint pow)
{
Matrix I;
while(pow)
{
if(pow & 1)
{
I = I * base;
}
base = base * base;
pow >>= 1;
}
return I;
}
int main()
{
lint t;
memset(C, 0, sizeof(C));
C[0][0] = 1LL;
C[1][0] = C[1][1] = 1LL;
for(int i = 2; i <= 50; i++)
{
for(int j = 0; j <= i; j++)
{
if(j == 0)
{
C[i][j] = 1LL;
}
else
{
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
}
}
}
scanf("%lld",&t);
for(lint cas = 1; cas <= t; cas++)
{
scanf("%lld %lld", &n, &k);
siz = k + 2;
Matrix tran;
memset(tran.a, 0, sizeof(tran.a));
for(int i = 1; i <= k + 1; i++)
{
for(int j = 1; j <= k + 1; j++)
{
if(i <= j)
{
tran.a[i][j] = C[k + 1 - i][j - i];
}
}
}
for(int i = 1; i <= k + 1; i++)
{
tran.a[k + 2][i] = C[k][i - 1];
}
tran.a[k + 2][k + 2] = 1LL;
Matrix ans = quick_pow(tran, n - 1);
lint answer = 0;
for(int i = 1; i <= k + 2; i++)
{
answer = (answer + ans.a[k + 2][i]) % mod;
}
printf("Case %lld: %lld\n", cas, answer);
}
return 0;
}