zoukankan      html  css  js  c++  java
  • [Codeforces 946F]Fibonacci String Subsequences

    Description

    题库链接

    定义 (F(x))(F(x-1))(F(x-2)) 的连接(其中 (F(0) = "0",F(1) = "1") )。给出一个长度为 (n)(01) 字符串 (s) ,询问 (s)(F(x)) 的所有子序列中出现了多少次。

    (1leq nleq 100,0leq xleq 100)

    Solution

    首先 (F(x)) 是递归来定义的,显然我们可以递推来计算答案。

    (f_{l,r,i}) 表示 (F(i)) 的所有子串中 (s_{lsim r}) 出现的次数。

    来考虑转移,一共有三部分:

    1. (lsim r) 完全在 (F(i-1)) 中。此时若 (r=n) ,那么可以在 (F(i-2)) 中乱选,则有 (2^{len(F(i-2))}) 种;若 (r eq n) ,因为不能在后面乱选,所以贡献只有 (1) 倍。
    2. (lsim r) 完全在 (F(i-2)) 中。这种讨论和 1. 中相同。
    3. 最后分为在不同的两段中,设 (s_{lsim k})(F(i-1)) 中;设 (s_{k+1sim r})(F(i-2)) 中。则 (f_{l,r,i}=f_{l,k,i-1} imes f_{k+1,r,i-2})

    Code

    //It is made by Awson on 2018.3.13
    #include <bits/stdc++.h>
    #define LL long long
    #define dob complex<double>
    #define Abs(a) ((a) < 0 ? (-(a)) : (a))
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
    #define writeln(x) (write(x), putchar('
    '))
    #define lowbit(x) ((x)&(-(x)))
    using namespace std;
    const int N = 100, yzh = 1e9+7;
    void read(int &x) {
        char ch; bool flag = 0;
        for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
        for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
        x *= 1-2*flag;
    }
    void print(LL x) {if (x > 9) print(x/10); putchar(x%10+48); }
    void write(LL x) {if (x < 0) putchar('-'); print(Abs(x)); }
    
    int n, x, g[N+5];
    int f[N+5][N+5][N+5];
    char ch[N+5];
    
    int quick_pow(int a, int b) {
        int ans = 1;
        while (b) {
        if (b&1) ans = 1ll*ans*a%yzh;
        b >>= 1, a = 1ll*a*a%yzh;
        }
        return ans;
    }
    void work() {
        read(n), read(x); scanf("%s", ch+1); g[0] = g[1] = 1;
        for (int i = 2; i <= x; i++) g[i] = (g[i-1]+g[i-2])%(yzh-1);
        for (int i = 0; i <= x; i++) g[i] = quick_pow(2, g[i]);
        for (int i = 1; i <= n; i++)
        if (ch[i] == '0') f[i][i][0] = 1; else f[i][i][1] = 1;
        for (int i = 2; i <= x; i++) {
        for (int l = 1; l <= n; l++)
            for (int r = l; r <= n; r++) {
            if (r == n) (f[l][r][i] += 1ll*f[l][r][i-1]*g[i-2]%yzh) %= yzh;
            else (f[l][r][i] += f[l][r][i-1]) %= yzh;
            if (l == 1) (f[l][r][i] += 1ll*f[l][r][i-2]*g[i-1]%yzh) %= yzh;
            else (f[l][r][i] += f[l][r][i-2]) %= yzh;
            for (int k = l; k < r; k++)
                (f[l][r][i] += 1ll*f[l][k][i-1]*f[k+1][r][i-2]%yzh) %= yzh;
            }
        }
        writeln(f[1][n][x]);
    }
    int main() {
        work(); return 0;
    }
  • 相关阅读:
    Hadoop 学习笔记 (十) hadoop2.2.0 生产环境部署 HDFS HA Federation 含Yarn部署
    hadoop 2.x 安装包目录结构分析
    词聚类
    Hadoop 学习笔记 (十一) MapReduce 求平均成绩
    Hadoop 学习笔记 (十) MapReduce实现排序 全局变量
    Hadoop 学习笔记 (九) hadoop2.2.0 生产环境部署 HDFS HA部署方法
    Visual Studio Code 快捷键大全(Windows)
    Eclipse安装教程 ——史上最详细安装Java &Python教程说明
    jquery操作select(取值,设置选中)
    $.ajax 中的contentType
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8560638.html
Copyright © 2011-2022 走看看