Codeforces 551D GukiZ and Binary Operations(矩阵快速幂)

转自http://www.cnblogs.com/keam37/p/4578568.html

 

  1 /*Author :usedrose  */
  2 /*Created Time :2015/8/7 12:26:39*/
  3 /*File Name :2.cpp*/
  4 #pragma comment(linker, "/STACK:1024000000,1024000000") 
  5 #include <cstdio>
  6 #include <iostream>
  7 #include <algorithm>
  8 #include <sstream>
  9 #include <cstdlib>
 10 #include <cstring>
 11 #include <climits>
 12 #include <vector>
 13 #include <string>
 14 #include <ctime>
 15 #include <cmath>
 16 #include <deque>
 17 #include <queue>
 18 #include <stack>
 19 #include <set>
 20 #include <map>
 21 #define INF 0x3f3f3f3f
 22 #define eps 1e-8
 23 #define pi acos(-1.0)
 24 #define MAXN 1110
 25 #define MAXM 100110
 26 #define OK cout << "ok" << endl;
 27 #define o(a) cout << #a << " = " << a << endl
 28 #define o1(a,b) cout << #a << " = " << a << "  " << #b << " = " << b << endl
 29 using namespace std;
 30 typedef long long ll;
 31 
 32 const int N = 2;
 33 ll n, k, l, m;
 34 
 35 struct Mat {
 36     ll mat[N + 1][N + 1];
 37 } A, B;
 38 
 39 Mat operator * ( Mat a, Mat b )
 40 {
 41     Mat c;
 42     memset ( c.mat, 0, sizeof c.mat );
 43     for ( int k = 0; k <  N; k++ )
 44         for ( int i = 0; i <  N; i++ )
 45             for ( int j = 0; j <  N; j++ )
 46                 ( c.mat[i][j] += ( a.mat[i][k] * b.mat[k][j] ) % m ) %= m;
 47     return c;
 48 }
 49 
 50 Mat operator ^ ( Mat a, ll pow )
 51 {
 52     Mat c;
 53     for ( int i = 0; i <  N; i++ )
 54         for ( int j = 0; j <  N; j++ )
 55             c.mat[i][j] = ( i == j );
 56     while ( pow ) {
 57         if ( pow & 1 )     c = c * a;
 58         a = a * a;
 59         pow >>= 1;
 60     }
 61     return c;
 62 }
 63 
 64 ll quickp( ll x )
 65 {
 66     ll s = 1, c = 2;
 67     while( x ) {
 68         if( x & 1 ) s = ( s * c ) % m;
 69         c = ( c * c ) % m;
 70         x >>= 1;
 71     }
 72     return s;
 73 }
 74 
 75 int main()
 76 {
 77     //freopen("data.in","r",stdin);
 78     //freopen("data.out","w",stdout);
 79     cin.tie(0);
 80     ios::sync_with_stdio(false);
 81     Mat p, a;
 82     p.mat[0][0] = 0, p.mat[0][1] = 1;
 83     p.mat[1][0] = 1, p.mat[1][1] = 1;
 84     a.mat[0][0] = 1, a.mat[0][1] = 2;
 85     a.mat[1][0] = 0, a.mat[1][1] = 0;
 86     cin >> n >> k >> l >> m;
 87     ll ans = 0;
 88     if (l == 64 || (1uLL<<l) > k ) {
 89         ans++;
 90         p = p ^ n;
 91         a = a * p;
 92         ll t1 = a.mat[0][0], t2 = (m + quickp(n) - t1)%m;
 93         for (int i = 0;i < l; ++ i) {
 94             if ((1uLL<<i)&k) 
 95                 ans = (ans*t2)%m;
 96             else ans = (ans*t1)%m;
 97         }
 98     }
 99     cout << ans%m << endl;
100 
101     return 0;
102 }
View Code

 

posted @ 2015-08-07 12:37  UsedRose  阅读(259)  评论(0编辑  收藏  举报