A Very Simple Problem
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1022 Accepted Submission(s): 500Problem DescriptionThis is a very simple problem. Given three integers N, x, and M, your task is to calculate out the following value:InputThere are several test cases. For each case, there is a line with three integers N, x, and M, where 1 ≤ N, M ≤ 2*109, and 1 ≤ x ≤ 50.
The input ends up with three negative numbers, which should not be processed as a case.OutputFor each test case, print a line with an integer indicating the result.Sample Input100 1 100003 4 1000-1 -1 -1Sample Output5050444Source
【分析】
感觉我的思想离正解还是太远太远,根本不会这样想。
首先我们发现x很小,k很大,k达到了10^9,for一遍都不行,这样我们就想到ans可能存在递推式,然后可以用矩阵加速。
转自:http://972169909-qq-com.iteye.com/blog/1863402
太厉害了,我自己都好难再推一次~~
代码如下:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 #define Maxn 60 10 #define LL long long 11 12 LL c[Maxn][Maxn]; 13 LL n,x,M; 14 15 struct node 16 { 17 LL a[Maxn][Maxn]; 18 }t[5]; 19 20 void init() 21 { 22 memset(c,0,sizeof(c)); 23 for(LL i=0;i<=50;i++) c[i][0]=1; 24 for(LL i=1;i<=50;i++) 25 for(LL j=1;j<=50;j++) 26 c[i][j]=(c[i-1][j-1]+c[i-1][j])%M; 27 } 28 29 void get_un() 30 { 31 memset(t[1].a,0,sizeof(t[1].a)); 32 for(LL i=0;i<=x+1;i++) t[1].a[i][i]=1%M; 33 } 34 35 void mul(LL now,LL y,LL z) 36 { 37 for(int i=0;i<=x+1;i++) 38 for(int j=0;j<=x+1;j++) 39 { 40 t[2].a[i][j]=0; 41 for(LL k=0;k<=x+1;k++) 42 t[2].a[i][j]=(t[2].a[i][j]+t[y].a[i][k]*t[z].a[k][j])%M; 43 } 44 t[now]=t[2]; 45 } 46 47 void qpow(LL b) 48 { 49 get_un(); 50 while(b) 51 { 52 if(b&1) mul(1,0,1); 53 mul(0,0,0); 54 b>>=1; 55 } 56 } 57 58 int main() 59 { 60 while(1) 61 { 62 scanf("%lld%lld%lld",&n,&x,&M); 63 if(n==-1&&x==-1&&M==-1) break; 64 init(); 65 for(LL i=0;i<=x;i++) 66 { 67 for(LL j=0;j<=i;j++) t[0].a[i][j]=(x*c[i][j])%M; 68 for(LL j=i+1;j<=x+1;j++) t[0].a[i][j]=0; 69 } 70 for(LL i=0;i<x;i++) t[0].a[x+1][i]=0; 71 t[0].a[x+1][x]=t[0].a[x+1][x+1]=1%M; 72 // get_un(); 73 qpow(n+1); 74 printf("%lld ",t[1].a[x+1][0]); 75 } 76 return 0; 77 }
2016-09-25 22:07:05