zoukankan      html  css  js  c++  java
  • Binary Strings Gym

    http://codeforces.com/gym/101161/attachments

    这题通过打表,可以知道长度是i的时候的合法方案数。

    然后得到f[1] = 2, f[2] = 3, f[3] = 5, f[4] = 8......这样的广义fib数列

    现在要求f[k] + f[2k] + f[3k] + ...... + f[xk]的总和。

    直接做很难做,我不知道f[i * k] = x * f[(i - 1) * k] + y * f[(i - 2) * k]

    推不出系数的话,有一个结论就是:fib的任意一项肯定能表示成x * f(i - 1) + y * f(i - 2),就是两个连续的fib数字,能表示出后面所有的fib数列。知道这样的东西后。

    可以知道,比如k = 2

    形如f(6) = 2 * f(4) + f(3)、然后f(8) = 2 * f(6) + f(5)

    那么就可以构造矩阵了。

    sum, f(4),f(3)   ----->   newSum, f(6), f(5)

    同样用f(4)和f(3)把f(5)表示出来即可(注意:肯定能表示)

    一般构造了矩阵后,写一个求第k项的函数出来,往往比较有用

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <bitset>
    #define X first
    #define Y second
    #define lson T[rt].l
    #define rson T[rt].r
    #define clr(u,v); memset(u,v,sizeof(u));
    #define in() freopen("data.txt","r",stdin);
    #define out() freopen("ans","w",stdout);
    #define Clear(Q); while (!Q.empty()) Q.pop();
    #define pb push_back
    
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    const int maxn = 5;
    const int MOD = 1e9 + 7;
    struct Matrix {
        LL a[maxn][maxn];
        int row, col;
    } base, a;
    struct Matrix mul(struct Matrix a, struct Matrix b, int MOD) {
        struct Matrix c = {0};
        c.row = a.row, c.col = b.col;
        for (int i = 1; i <= a.row; ++i) {
            for (int j = 1; j <= b.col; j++) {
                for (int k = 1; k <= b.row; ++k) {
                    c.a[i][j] += a.a[i][k] * b.a[k][j];
                    c.a[i][j] %= MOD;
                }
            }
        }
        return c;
    }
    struct Matrix qp(Matrix ans, Matrix base, LL n, LL MOD) {
        while (n) {
            if (n & 1) {
                ans = mul(ans, base, MOD);
            }
            n >>= 1;
            base = mul(base, base, MOD);
        }
        return ans;
    }
    int f;
    void initBaseFib() {
        base.row = base.col = 2;
        base.a[1][1] = 1, base.a[1][2] = 1;
        base.a[2][1] = 1, base.a[2][2] = 0;
    }
    LL findK(int a, int b, LL k) {
        if (k == 1) return a;
        if (k == 2) return b;
        initBaseFib();
        Matrix t;
        t.row = 1, t.col = 2;
        t.a[1][1] = b, t.a[1][2] = a;
        t = qp(t, base, k - 2, MOD);
        return t.a[1][1];
    }
    void initBaseSum(int a, int b, int c, int d) {
        base.row = base.col = 3;
        base.a[1][1] = 1, base.a[1][2] = 0, base.a[1][3] = 0;
        base.a[2][1] = 1, base.a[2][2] = a, base.a[2][3] = b;
        base.a[3][1] = 0, base.a[3][2] = c, base.a[3][3] = d;
    }
    int pre[22];
    int sum[22];
    LL getpos(LL n, LL k) {
        if (n == 0) return 0;
        if (n == 1) return findK(2, 3, n * k);
        if (k == 2) {
            initBaseSum(2, 1, 1, 1);
            Matrix t;
            t.row = 1, t.col = 3;
            t.a[1][1] = 3, t.a[1][2] = 8, t.a[1][3] = 5;
            t = qp(t, base, n - 1, MOD);
            return t.a[1][1];
        } else if (k == 3) {
            initBaseSum(3, 2, 2, 1);
            Matrix t;
            t.row = 1, t.col = 3;
            t.a[1][1] = 5, t.a[1][2] = 21, t.a[1][3] = 13;
            t = qp(t, base, n - 1, MOD);
            return t.a[1][1];
        } else {
            Matrix t;
            t.row = 1, t.col = 3;
            t.a[1][1] = findK(2, 3, k), t.a[1][2] = findK(2, 3, 2 * k), t.a[1][3] = findK(2, 3, 2 * k - 1);
            initBaseSum(findK(2,3,k-1), findK(2,3,k-2), findK(2,3,k-2), findK(2,3,k-3));
            t = qp(t, base, n - 1, MOD);
            return t.a[1][1];
        }
    }
    void work() {
        LL be, en, k;
        cin >> be >> en >> k;
        if (k == 1) {
            //sumofall fib
            if (en <= 2) {
                printf("Case %d: %d
    ", ++f, sum[en] - sum[be - 1]);
                return;
            }
    
            initBaseSum(1, 1, 1, 0);
            be--;
            a.row = 1, a.col = 3;
            a.a[1][1] = 2, a.a[1][2] = 3, a.a[1][3] = 2;
            Matrix ret = qp(a, base, en - 1, MOD);
            LL resEn = ret.a[1][1];
            LL resBe = 0;
            if (be - 1 >= 0) {
                ret = qp(a, base, be - 1, MOD);
                resBe = ret.a[1][1];
            }
            printf("Case %d: %d
    ", ++f, (resEn - resBe + MOD) % MOD);
            return;
        } else {
            en = en / k;
            if (be % k == 0) be = (be - k) / k;
            else be /= k;
    //        cout << be << " " << en << endl;
            LL ans = (getpos(en, k) - getpos(be, k) + MOD) % MOD;
            printf("Case %d: %d
    ", ++f, ans);
        }
    }
    int cnt[22];
    void dfs(int k, int t1, int t2) {
        if (k == t1 || k == t2) {
            cnt[k]++;
            return;
        }
        dfs(k - 1, t1, t2);
        dfs(k - 2, t1, t2);
    }
    int main() {
    #ifdef local
        in();
    #else
    #endif
        pre[1] = 2, pre[2] = 3, pre[3] = 5, pre[4] = 8;
        sum[1] = 2, sum[2] = 5, sum[3] = 10, sum[4] = 18;
    //    int one = 6, t1 = 4, t2 = 2;
    //    dfs(one, t1, t2);
    //    cout << cnt[t1] << " " << cnt[t2] << endl;
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
  • 相关阅读:
    HTTP学习三:HTTPS
    JavaScript判断变量的类型
    用JS创建10个<a>标签,点击的时候弹出来对应的序号
    【工具】根据后端提供的swagger生成前端的axios请求配置文件/api
    JavaScript正则表达式-零宽断言
    JavaScript中数组去重、对象去重的方法
    收集的无版权图片网站(欢迎补充)
    css 清除浮动
    JavaScript+CSS+HTML 编写手风琴效果
    Mac定制终端:iTerm2 + zsh + powerline
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7309998.html
Copyright © 2011-2022 走看看