lightoj1132—Summing up Powers (取膜技巧&&组合数应用)

题目链接:https://vjudge.net/problem/LightOJ-1132

题目意思:(1K + 2K + 3K + ... + NK) % 232


矩阵快速幂的题目一般都很短,这道题也一样就是这么简单。

思路:运用到了组合数a^k=C(k,0)*a^k+C(k,1)*a^(k-1)+C(k,2)*a^(k-2)+C(k,3)*a^(k-3)+C(k,4)*a^(k-4)+……C(k,k)*a^(k-k),运用这个式子我们可以构造以下矩阵。

 1 C(k,0),   C(k,1),   C(k,2),   C(k,3)………… …… C(k,k)     0    (n-1)^k            (n)^k
 2 C(k-1,0), C(k-1,1), C(k-1,2), C(k-1,3)…………C(k-1,k-1)   0    (n-1)^(k-1)        (n)^(k-1) 
 3 C(k-2,0), C(k-2,1), C(k-2,2), C(k-2,3)…………C(k-2,k-2)   0    (n-1)^(k-2)        (n)^(k-2) 
 4 C(k-3,0), C(k-3,1), C(k-3,2), C(k-3,3)…………C(k-3,k-3)   0    (n-1)^(k-3)    =   (n)^(k-3)
 5 ……………………                                            *  0
 6 ……………………                                           0
 7 ……………………                                              0
 8 C(3,0), C(3,1), C(3,2), C(3,3)                           0    (n-1)^(3)          (n)^(3)
 9 C(2,0), C(2,1), C(2,2)                                   0    (n-1)^(2)          (n)^(2)
10 C(1,0), C(1,1)                                           0    (n-1)^(1)          (n)^(1)
11 C(k,0),   C(k,1),   C(k,2),   C(k,3)………… …… C(k,k)     1    s(n-1)             s[n]

还有一点这道题有一个奇怪的mod数2^32对于这个膜数我们采用unsigned int自然溢出就好了,如果直接mod就会超时,这一点在以后遇到这个mod数的时候需要注意。

代码:

 1 //Author: xiaowuga
 2 #include<bits/c++.h>
 3 #define maxx INT_MAX
 4 #define minn INT_MIN
 5 #define inf 0x3f3f3f3f
 6 
 7 using namespace std;
 8 typedef unsigned int ll;
 9 long long n,size;
10 struct Matrix{
11     ll mat[55][55];
12     void clear(){
13         memset(mat,0,sizeof(mat));
14     }
15     Matrix operator * (const Matrix & m) const{
16         Matrix tmp;
17         int i ,j,k;
18         tmp.clear();
19         for( i=0;i<=size+1;i++)
20             for( k=0;k<=size+1;k++){
21                 if(mat[i][k]==0) continue;
22                 for( j=0;j<=size+1;j++){
23                     tmp.mat[i][j]+=mat[i][k]*m.mat[k][j];
24                     //tmp.mat[i][j]%=MOD;
25                 }
26             }
27         return tmp;
28     }
29 };
30 Matrix POW(Matrix m,long long k){
31     Matrix ans;
32     memset(ans.mat,0,sizeof(ans.mat));
33     for(int i=0;i<=size+1;i++) ans.mat[i][i]=1;
34     while(k){
35         if(k&1) ans=ans*m;
36         k=k>>1;
37         m=m*m;
38     }
39     return ans;
40 }
41 int main() {
42      ll tranangle[55][55]={0};
43      tranangle[0][0]=1;
44      for(int i=1;i<55;i++){
45          tranangle[i][0]=1;
46          for(int j=1;j<=i;j++)
47              tranangle[i][j]=tranangle[i-1][j]+tranangle[i-1][j-1];
48      }
49      int T;
50      scanf("%d",&T);
51     for(int Case=1;Case<=T;Case++){
52        scanf("%lld%lld",&n,&size);
53         Matrix m;
54         memset(m.mat,0,sizeof(m.mat));
55         for(int i=0;i<=size;i++){
56             for(int j=0;j<=size;j++)
57                 m.mat[i][j]=tranangle[i][j];
58         }
59         for(int i=0;i<=size;i++)
60              m.mat[size+1][i]=tranangle[size][i];
61         m.mat[size+1][size+1]=1;
62         Matrix ans=POW(m,n-1);
63         ll sum=0;
64         for(int i=0;i<=size+1;i++){
65             sum+=ans.mat[size+1][i];
66         }
67         printf("Case %d: %lld
",Case,sum);
68     }
69     return 0;
70 }
View Code
原文地址:https://www.cnblogs.com/xiaowuga/p/7354674.html