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


    Problem D. GukiZ and Binary Operations

    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
  • 相关阅读:
    SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSAS 系列
    微软BI 之SSRS 系列
    微软BI 之SSRS 系列
    配置 SQL Server Email 发送以及 Job 的 Notification通知功能
  • 原文地址:https://www.cnblogs.com/keam37/p/4578568.html
Copyright © 2020-2023  润新知