lightoj1132

题意:给你n和k,要你求出(1K + 2K + 3K + ... + NK) % 232

这道题暴露了我好多问题,好像本来就有很多问题!

首先对数字不敏感,这个数字可以通过开unsigned int让它自然溢出。所以不用模运算,用模运算反而会超时。

然后就是公式的设置,这个不用多说,设f(n)=(1^k+...+n^k),自然就可以得到f(n)=f(n-1)+n^k,然后就是做这类题目的常见套路,不是从f(n)想递推公式,而是通过f(n+1),为什么这样,原因是这样式子会整齐一点,好看一点!

然后程序一定要该写的地方数值一定要写对,一定要写对!

接下来是代码:

       

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ll;
 4 ll C[60][60];
 5 int t;
 6 long long n,k1,mod=1;
 7 ll lc[60][60],ans[60][2];
 8 
 9 
10 void init(){
11     memset(lc,0,sizeof(lc));
12     memset(ans,0,sizeof(ans));
13     for(int i=1;i<=k1+2;i++) ans[i][1]=1;
14     for(int i=1;i<=k1+2;i++){
15         if(i==1){
16             lc[1][1]=1;
17             for(int j=2;j<=k1+2;j++) lc[1][j]=C[k1][j-2];
18         }else{
19             for(int j=i;j<=k1+2;j++) lc[i][j]=C[k1-i+2][j-i];
20         }
21     }    
22 }
23 
24 void C_(){
25     C[0][0]=1;
26     for(int i=1;i<=55;i++){
27         C[i][0]=C[i][i]=1;
28         for(int j=1;j<i;j++){
29             C[i][j]=(C[i-1][j-1]+C[i-1][j]);
30         }
31     }    
32 }
33 
34 void mul(){
35     ll temp[60][2];
36     memset(temp,0,sizeof(temp));
37     for(int i=1;i<=k1+2;i++){
38         for(int j=1;j<=1;j++){
39             for(int k=1;k<=k1+2;k++){
40                 temp[i][j]=(temp[i][j]+lc[i][k]*ans[k][j]);
41             }
42         }
43     }
44     for(int i=1;i<=k1+2;i++) ans[i][1]=temp[i][1];
45 }
46 
47 void add(){
48     ll temp[60][60];
49     memset(temp,0,sizeof(temp));
50     for(int i=1;i<=k1+2;i++){
51         for(int j=1;j<=k1+2;j++){
52             for(int k=1;k<=k1+2;k++){
53                 temp[i][j]=(temp[i][j]+lc[i][k]*lc[k][j]);
54             }
55         }
56     }
57     for(int i=1;i<=k1+2;i++)
58         for(int j=1;j<=k1+2;j++)
59             lc[i][j]=temp[i][j];
60 }
61 
62 void fast_pow(long long m){//这些参数的传递一定要非常非常小心 
63     while(m){
64         if(m%2==1) mul();
65         add();
66         m/=2;
67     }
68     cout<<ans[1][1]<<endl;    
69 }
70 
71 int main(){
72     C_();
73     cin>>t;
74     for(int i=1;i<=32;i++) mod*=2;
75     for(int kase=1;kase<=t;kase++){
76         cin>>n>>k1;
77         if(n==1){
78             cout<<"Case "<<kase<<": 1"<<endl;
79             continue;
80         }
81         if(k1==0){
82             cout<<"Case "<<kase<<": "<<n%mod<<endl;
83             continue;
84         }
85         init();
86         cout<<"Case "<<kase<<": ";
87         fast_pow(n-1);
88     }
89     return 0;
90 }
View Code

猜你喜欢

转载自www.cnblogs.com/pandaking/p/9975891.html