zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    友盟页面统计
    为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?
    让jQuery的ajaxFileUpload插件支持onchange事件
    sublime双击选择全选带中划线
    配置Chrome Workspace功能
    font-face 跨域解决
    Yahoo团队经验:网站性能优化的34条黄金法则
    require.js+knockout.js+.underscore模板引擎的使用
    使用livereload实现自动刷新
    WebStorm 7.0 支持更多的Web技术
  • 原文地址:https://www.cnblogs.com/zhuiyicc/p/10052462.html
Copyright © 2011-2022 走看看