码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-06-15 18:29:18      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:

Problem E. GukiZ and GukiZiana

Solution 

      一位一位考虑,就是求一个二进制序列有连续的1的种类数和没有连续的1的种类数。

     没有连续的1的二进制序列的数目满足f[i]=f[i-1]+f[i-2],恰好是斐波那契数列。

     数据范围在10^18,用矩阵加速计算,有连续的1的数目就用2^n-f[n+1]

     最后枚举k的每一位,是1乘上2^n-f[n+1],是0乘上f[n+1]

     注意以上需要满足 2^l>k。并且这里l的最大值为64,需要特判。

 

技术分享
#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ll;
const int N = 2;
ll n, k, l, m;

struct Mat {
    ll mat[N + 1][N + 1];
} A, B;

Mat operator * ( Mat a, Mat b )
{
    Mat c;
    memset ( c.mat, 0, sizeof c.mat );
    for ( int k = 0; k <  N; k++ )
        for ( int i = 0; i <  N; i++ )
            for ( int j = 0; j <  N; j++ )
                ( c.mat[i][j] += ( a.mat[i][k] * b.mat[k][j] ) % m ) %= m;
    return c;
}

Mat operator ^ ( Mat a, ll pow )
{
    Mat c;
    for ( int i = 0; i <  N; i++ )
        for ( int j = 0; j <  N; j++ )
            c.mat[i][j] = ( i == j );
    while ( pow ) {
        if ( pow & 1 )     c = c * a;
        a = a * a;
        pow >>= 1;
    }
    return c;
}

ll quickp( ll x )
{
    ll s = 1, c = 2;
    while( x ) {
        if( x & 1 ) s = ( s * c ) % m;
        c = ( c * c ) % m;
        x >>= 1;
    }
    return s;
}
int main()
{
    ios::sync_with_stdio( 0 );
    Mat p, a;
    p.mat[0][0] = 0, p.mat[0][1] = 1;
    p.mat[1][0] = 1, p.mat[1][1] = 1;
    a.mat[0][0] = 1, a.mat[0][1] = 2;
    a.mat[1][0] = 0, a.mat[1][1] = 0;
    cin >> n >> k >> l >> m;

    ll ans = 0;
    if(  l == 64 || ( 1uLL << l ) > k  ) {
        ans++;
        p = p ^ n;
        a = a * p;
        ll t1 = a.mat[0][0], t2 = ( m + quickp( n ) - t1 ) % m;
        for( int i = 0; i < l; ++i ) {
            if( k & ( 1uLL << i ) ) ans = ( ans * t2 ) % m;
            else ans = ( ans * t1 ) % m;
        }
    }

    cout << ans%m << endl;

}
View Code

 

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

标签:

原文地址:http://www.cnblogs.com/keam37/p/4578568.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!