1132 - Summing up Powers
Time Limit: 2 second(s) | Memory Limit: 32 MB |
Given N and K, you have to find
(1K + 2K + 3K + ... + NK) % 232
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case contains two integers N (1 ≤ N ≤ 1015) and K (0 ≤ K ≤ 50) in a single line.
Output
For each case, print the case number and the result.
Sample Input | Output for Sample Input |
3 3 1 4 2 3 3 | Case 1: 6 Case 2: 30 Case 3: 36 |
思路:设Fn = N^k,F(n+1)=(N+1)^k,按照二项式展开,根据这个展开式就可以推出初始矩阵……
这个题一直TLE,,我感到非常不理解……后来终于发现把MOD定义为const就A了(刚开始我只是定义成全局变量,没有加const)……get了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int N = 55;
LL k;
const LL MOD = (LL)1 << 32;
LL c[N][N];
struct Mat {
LL mat[N][N];
Mat operator *(const Mat &a)const {
Mat tmp;
for(int i = 0; i <= k+1; i++)
for(int j = 0; j <= k+1; j++) {
tmp.mat[i][j] = 0;
for(int l = 0; l <= k+1; l++)
tmp.mat[i][j] += mat[i][l] * a.mat[l][j] % MOD;
tmp.mat[i][j] %= MOD;
}
return tmp;
}
};
LL quick(LL n) {
if(n <= 1)return 1;
n--;
Mat ans;
memset(ans.mat,0,sizeof(ans.mat));
for(int i = 0; i <= k+1; i++)ans.mat[i][i] = 1;
Mat tmp;
memset(tmp.mat,0,sizeof(tmp.mat));
for(int j = 0; j <= k; j++) {
int tt = 0;
for(int i = j; i <= k; i ++,tt++)tmp.mat[j][i] = c[k-j][tt];
}
for(int i = 0; i < k+1; i++)tmp.mat[k+1][i] = tmp.mat[0][i];
tmp.mat[k+1][k+1] = 1;
while(n) {
if(n % 2)ans = ans * tmp;
tmp = tmp * tmp;
n /= 2;
}
LL res = 0;
for(int i = 0; i <= k+1; i++)
res = (res + ans.mat[k+1][i] % MOD) % MOD;
return res;
}
void Com() {
c[0][0] = 1;
for(int i = 1; i <= N; i++) {
c[i][0] = 1;
for(int j = 1; j <= i; j++)
c[i][j] = c[i][j-1] * (i-j+1) / j;
}
}
int main() {
// freopen("in.txt","r",stdin);
int x,y,t;
LL n;
Com();
scanf("%d",&t);
for(int i = 1; i <= t; i++) {
scanf("%lld%d",&n,&k);
printf("Case %d: %lld\n",i,quick(n));
}
return 0;
}