• Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations


    得到k二进制后,对每一位可取得的方法进行相乘即可,k的二进制形式每一位又分为2种0,1,0时,a数组必定要为一长为n的01串,且串中不出现连续的11,1时与前述情况是相反的。

    且0时其方法总数为f(n) = f(n-1) + f(n-2),其中f(2) = 3,f(1) = 3。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    ll n,k;
    int l,m;
    unsigned long long p[65];
    queue<int> q;
    //0: f[n] = f[n-2] + f[n-1]
    //1: 2^i - f[n]
    struct matrix{
        ll a[2][2];
        matrix(){
            a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0;
        }
        void unit(){
            a[0][0] = a[1][1] = 1;
        }
        matrix operator * (const matrix& p){
            matrix ans;
            for(int i = 0;i < 2;++i){
                for(int j = 0;j < 2;++j){
                    for(int k = 0;k < 2;++k){
                        ans.a[i][j] += a[i][k] * p.a[k][j];
                        if(ans.a[i][j] >= m) ans.a[i][j] %= m;
                    }
                }
            }
            return ans;
        }
    };
    ll fi(){
        //f[1] = 2,f[2] = 3;
        if(n == 1) return 2;
        if(n == 2) return 3;
        ll t = n;
        t -= 2;
        matrix ans,p;
        p.a[0][0] = 1,p.a[1][0] = 1,p.a[0][1] = 1;
        ans.unit();
        while(t){
            if(t & 1) ans = ans * p;
            p = p * p;
            t >>= 1;
        }
        return (3 * ans.a[0][0] + 2 * ans.a[1][0])%m;
    }
    ll quickpow(ll x,ll y){
        ll ans = 1;
        while(y){
            if(y & 1){
                ans = ans * x;
                if(ans >= m) ans %= m;
            }
            x *= x;
            if(x >= m) x %= m;
            y >>= 1;
        }
        return ans;
    }
    void solve(){
        if(p[l] - 1 < (unsigned long long)k && l != 64){
            puts("0");
            return;
        }
        while(k){
            q.push(k&1);
            k>>=1;
        }
        ll x = fi(),y = (quickpow(2,n) - x + m) % m,ans = 1;
        for(int i = 0;i < l;++i){
            if(!q.empty()){
                if(q.front()) ans = ans * y;
                else ans = ans * x;
                q.pop();
            }
            else{
                ans = ans * x;
            }
            if(ans >= m) ans %= m;
        }
        printf("%I64d
    ",ans%m);
    }
    int main()
    {
        cin >> n >> k >> l >> m;
        p[0] = 1;
        for(int i = 1;i < 64;++i) p[i] = p[i-1]*2;
        solve();
        return 0;
    }
  • 相关阅读:
    解决centos yum源配置出现Couldn't resolve host 问题
    Centos7下MongoDB下载安装详细步骤
    PHP操作mongodb扩展的坑 及php7安装mongodb扩展
    阿里云 Composer 全量镜像
    centos beanstalkd 安装 与php调用
    centos与windows共享文件夹
    centos php 安装编译 常见报错
    [PHP] layui实现多图上传,图片自由排序,自由删除
    Vue-element-admin实现菜单根据用户权限动态加载
    迭代器的使用方法
  • 原文地址:https://www.cnblogs.com/zhuiyicc/p/10052462.html
Copyright © 2020-2023  润新知