A sequence Sn is defined as:
Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn.
You, a top coder, say: So easy!
矩阵快速幂
1 #include<stdio.h>
2 #include<string.h>
3 #include<math.h>
4 typedef long long ll;
5 int mod;
6
7 struct mat{
8 int r,c;
9 ll m[4][4]; //经测试最大开成590*590的 ll 型矩阵
10 mat(){}
11 mat(int r,int c):r(r),c(c){}
12 void clear(){
13 memset(m,0,sizeof(m));
14 }
15
16 mat operator+(mat a)const{
17 mat ans(r,c);
18 for(int i=1;i<=r;i++){
19 for(int j=1;j<=c;j++){
20 ans.m[i][j]=(m[i][j]+a.m[i][j])%mod;
21 }
22 }
23 return ans;
24 }
25
26 mat operator*(mat a)const{
27 mat tmp(r,a.c);
28 int i,j,k;
29 for(i=1;i<=tmp.r;i++){
30 for(j=1;j<=tmp.c;j++){
31 tmp.m[i][j]=0;
32 for(k=1;k<=c;k++){
33 tmp.m[i][j]=(tmp.m[i][j]+(m[i][k]*a.m[k][j])%mod)%mod;
34 }
35 }
36 }
37 return tmp;
38 }
39
40 mat operator^(int n)const{ //需要时可以用 ll n,注意运算符优先级比较低,多用括号;
41 mat ans(r,r),tmp(r,r);
42 memcpy(tmp.m,m,sizeof(tmp.m));
43 ans.clear();
44 for(int i=1;i<=ans.r;i++){
45 ans.m[i][i]=1;
46 }
47 while(n){
48 if(n&1)ans=ans*tmp;
49 n>>=1;
50 tmp=tmp*tmp;
51 }
52 return ans;
53 }
54
55 void print()const{
56 for(int i=1;i<=r;i++){
57 for(int j=1;j<=c;j++){
58 printf("%lld",m[i][j]);
59 if(j==c)printf("
");
60 else printf(" ");
61 }
62 }
63 }
64
65 };
66
67 int main(){
68 ll a,b,n;
69 while(scanf("%lld%lld%lld%d",&a,&b,&n,&mod)!=EOF){
70 if(n==1){
71 printf("%lld
",(2*a)%mod);
72 continue;
73 }
74 mat tmp(2,2),t(2,1);
75 tmp.m[1][1]=(2*a)%mod;
76 tmp.m[1][2]=((b%mod-(a*a)%mod)%mod+mod)%mod;
77 tmp.m[2][1]=1;
78 tmp.m[2][2]=0;
79 t.m[1][1]=((2*a)%mod)*a%mod+(2*(b%mod))%mod;
80 t.m[2][1]=(2*a)%mod;
81 t=(tmp^(n-2))*t;
82 printf("%lld
",t.m[1][1]);
83 }
84 return 0;
85 }