LightOJ

来源:互联网 发布:抢票软件开发 编辑:程序博客网 时间:2024/06/16 10:15

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

3

3 1

4 2

3 3

Sample Output

Case 1: 6

Case 2: 30

Case 3: 36

没什么好说的,普通的快速幂肯定会超时,所以这里就用到矩阵快速幂。

这个问题最重要的是推出状态转移方程。



把操作矩阵D表示出来即可

#include<iostream>#include<stdio.h>#include<string>#include<math.h>#include<vector>#include<string.h>#include<iterator>using namespace std;typedef unsigned long long ll;ll n,k;const ll mod = ((ll)1<<32);struct Matrix{    ll a[55][55];    void init(){        for(int i = 0; i< k+ 2 ;i++){            for(int j = 0; j< k + 2; j ++){                if(i==j)                    a[i][j] = 1;                else                    a[i][j] = 0;            }        }    }    void init2(){        for(int i = 0; i< k+ 2 ;i++){            for(int j = 0; j< k + 2; j ++){                a[i][j] = 0;            }        }    }}A;//矩阵表示void init1(){    int i,j;    A.a[0][0] = 1;    for(i=1;i<k+2;i++){        for(j=0;j<i;j++){            A.a[i][j] = 0;        }    }    for(i=0;i<k+2;i++)        A.a[i][k+1] = 1;    for(i=k;i>0;i--){        for(j=k;j>=0;j--){            A.a[i][j] = A.a[i+1][j] + A.a[i+1][j+1];        }    }    for(j=1;j<k+2;j++)        A.a[0][j] = A.a[1][j];    /*for(i=0;i<k+2;i++){        for(j=0;j<k+2;j++){            cout<<A.a[i][j]<<" ";        }        cout<<endl;    }*/}Matrix multiply(Matrix x,Matrix y){    Matrix ans;    ans.init2();    for(int i = 0 ;i < k+2; i++){        for(int p = 0; p < k+2 ;p++)        for(int j = 0; j < k+2; j++){//改变p和j的顺序能有效的改进复杂度                ans.a[i][j]=(ans.a[i][j]+(x.a[i][p]*y.a[p][j])%mod)%mod;//注意取模的地方            }        }    return ans;}//矩阵的乘法Matrix Matrix_pow(Matrix ma,ll n){    Matrix ans;    ans.init();    while(n){        if(n%2==1)            ans = multiply(ans,ma);        ma = multiply(ma,ma);        n>>=1;    }    return ans;}//矩阵的快速幂int main(){    int t;    int i,j;    ll result;    int a,b;    scanf("%d",&t);    for(j=1;j<=t;j++){        scanf("%lld %lld",&n,&k);        init1();        result = 0;        Matrix x = Matrix_pow(A,n-1);        /*for(a = 0 ;a<k+2;a++){            for(b=0;b<k+2;b++){                cout<<x.a[a][b]<<" ";            }            cout<<endl;        }*/        for(i=0;i<k+2;i++){            result = (result + x.a[0][i]%mod)%mod;        }        cout<<"Case "<<j<<": "<<result<<endl;    }    return 0;}





原创粉丝点击