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

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;

}

时间: 2024-11-06 11:58:25

Codeforces 551D GukiZ and Binary Operations(矩阵快速幂)的相关文章

GukiZ and Binary Operations(矩阵+二进制)

D. GukiZ and Binary Operations time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output We all know that GukiZ often plays with arrays. Now he is thinking about this problem: how many arrays a, of l

Codeforces Round #257 (Div. 2)B 矩阵快速幂

B. Jzzhu and Sequences time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, please calculate fn m

Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP

题意: 给一个\(n\)点\(m\)边的连通图 每个边有一个权值\(d\) 当且仅当当前走过的步数\(\ge d\)时 才可以走这条边 问从节点\(1\)到节点\(n\)的最短路 好神的一道题 直接写做法喽 首先我们对边按\(d_i\)由小到大排序 设\(f_i\)表示加上\(1\sim i-1\)的所有边走\(d_i\)次后各点间的联通情况 \(G\)表示只连\(1\sim i-1\)的边的邻接矩阵 这些我们可以用一个\(01\)邻接矩阵来存储 则有 \(f_i=f_{i-1}*G^{d_i-

Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)

传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\end{aligned} \] 思路 我们通过迭代发现\(f_n\)其实就是由\(c^{x_1},f_1^{x_2},f_2^{x_3},f_3^{x_4}\)相乘得到,因此我们可以分别用矩阵快速幂求出\(x_1,x_2,x_3,x_4\),最后用快速幂求得答案. 对\(f_1,f_2,f_3\): \[ \begin{aligned} (x_n&&

Codeforces 696D Legen...(AC自动机 + 矩阵快速幂)

题目大概说给几个字符串,每个字符串都有一个开心值,一个串如果包含一次这些字符串就加上对应的开心值,问长度n的串开心值最多可以是多少. POJ2778..复习下..太弱了都快不会做了.. 这个矩阵的乘法定义是不同的,m[i][j]=max(m1[i][k]+m2[k][j]),即从i走到k能获得的最大值与从k走到j能获得的最大值之和去更新从i到j能获得的最大值. 另外..关于矩阵内的初始值..用-1表示从i不能到j,比如初始的时候,i不能走一步到j结点这时值就应该设置成-1:而不能用0,因为0是有

Codeforces 576D Flights for Regular Customers 矩阵快速幂 (看题解)

Flights for Regular Customers 临接矩阵的 k 次 就是 恰好 走 k 步从 i 走到 j 的方案数, 方案数在这里并不关键, 所以可以把它变成01矩阵. 一个很直观的想法是用二分取check它, 但是这并不单调.. 然后就不会了.. 我们可以把G[ n - 1] [ n - 1 ] 变成  1 , 这个函数就变成单调了, 然后直接二分check就好了, 可以用bitset优化一下, 不优化其实也能过. 还有一种方法就是, 每新加入一条边, 我们暴力跑一遍图取chec

D. GukiZ and Binary Operations(矩阵+二进制)

D. GukiZ and Binary Operations We all know that GukiZ often plays with arrays. Now he is thinking about this problem: how many arrays a, of length n, with non-negative elements strictly less then 2l meet the following condition: ? Here operation  mea

Codeforces 551 D. GukiZ and Binary Operations

\(>Codeforces \space 551 D. GukiZ and Binary Operations<\) 题目大意 :给出 \(n, \ k\) 求有多少个长度为 \(n\) 的序列 \(a\) 满足 \((a_1\ and \ a_2)or(a_2\ and \ a_3)or..or(a_{n-1}\ and \ a_n) = k\) 且 \(a_i \leq k \leq 2^l\) 并输出方案数在$\mod m $ 意义下的值 \(0≤?n ≤?10^{18},\ 0?≤?k

【矩阵快速幂 】Codeforces 450B - Jzzhu and Sequences (公式转化)

[题目链接]click here~~ [题目大意] Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, please calculate fn modulo1000000007(109?+?7). [解题思路] /*A - Jzzhu and Sequences Codeforces 450B - Jzzhu and Sequences ( 矩阵快速幂 )