zoukankan      html  css  js  c++  java
  • BZOJ5337 [TJOI2018] 碱基序列 【哈希】【动态规划】

    题目分析:

    这道题的难点在于要取模,而题面没有写。

    容易想到一个O(1E7)的dp。KMP或者哈希得到相关位置然后对于相关位置判断上一个位置有多少种情况。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 10200;
     5 
     6 const int mod = 1000000007;
     7 
     8 int n;
     9 string str;
    10 string fm[102][12];
    11 int num[102];
    12 
    13 const int Kh = 2;
    14 
    15 struct hnum{
    16     int base;
    17     unsigned long long multi[10200];
    18     unsigned long long hash[10200];
    19 }h[2];
    20 
    21 void read(){
    22     ios::sync_with_stdio(false);
    23     cin.tie();
    24     cin >> n;
    25     cin >> str;
    26     for(int i=1;i<=n;i++){
    27     cin >> num[i];
    28     for(int j=1;j<=num[i];j++) {cin >> fm[i][j];}
    29     }
    30 }
    31 
    32 long long rm[2][maxn];
    33 int d[maxn];
    34 
    35 void KMP(int c,int m){
    36     memset(d,0,sizeof(d));
    37     string &p = fm[c][m];
    38     for(int o = 0;o<Kh;o++){
    39     unsigned long long now = 0;
    40     for(int i=0;i<p.length();i++)
    41         now += (p[i]-'A'+1)*h[o].multi[i];
    42     for(int i=p.length()-1;i<str.length();i++){
    43         unsigned long long data;
    44         if(i!=p.length()-1)data = h[o].hash[i]-h[o].hash[i-p.length()];
    45         else data = h[o].hash[i];
    46         if(now == data) d[i]++;
    47         now = now*h[o].base;
    48     }
    49     }
    50     for(int i=0;i<str.length();i++) if(d[i]==Kh)d[i]=1;else d[i]=0;
    51 }
    52 
    53 void build_hash(){
    54     for(int i=0;i<Kh;i++){
    55     h[i].multi[0] = 1;
    56     for(int j=1;j<str.length();j++){
    57         h[i].multi[j] = h[i].multi[j-1]*h[i].base;
    58     }
    59     h[i].hash[0] = str[0]-'A'+1;
    60     for(int j=1;j<str.length();j++){
    61         h[i].hash[j] = h[i].hash[j-1]+(str[j]-'A'+1)*h[i].multi[j];
    62     }
    63     }
    64 }
    65 
    66 void work(){
    67     h[0].base = 19,h[1].base = 31;
    68     build_hash();
    69     for(int i=1;i<=num[1];i++){
    70     KMP(1,i); for(int k=0;k<str.length();k++) rm[1][k] += d[k];
    71     }
    72     for(int i=2;i<=n;i++){
    73     memset(rm[i&1],0,sizeof(rm[i&1]));
    74     for(int j=1;j<=num[i];j++){
    75         KMP(i,j); int len = fm[i][j].length();
    76         for(int k=0;k<str.length();k++){
    77         if(d[k]){
    78             if(k-len<0) continue;
    79             rm[i&1][k] += rm[(i+1)&1][k-len];
    80             rm[i&1][k] %= mod;
    81         }
    82         }
    83     }
    84     }
    85     long long ans = 0;
    86     for(int j=0;j<str.length();j++){
    87     ans += rm[n&1][j]; ans %= mod;
    88     }
    89     printf("%lld",ans);
    90 }
    91 
    92 int main(){
    93     read();
    94     work();
    95     return 0;
    96 }
  • 相关阅读:
    python加载csv数据
    Android项目依赖库管理方式简介
    Android PhotoView基本功能实现
    Android ListView的header footer设置visibility gone不起作用
    [干货][EMIT]千行代码实现代理式AOP+属性的自动装配
    Emit实现DataRow转化成强类型的T
    有关docker新版的icc、iptables的一个巨坑
    Mac神器Iterm2的Shell Integration的用法和注意事项
    生成ssl证书文件
    python3 module中__init__.py的需要注意的地方
  • 原文地址:https://www.cnblogs.com/Menhera/p/9060947.html
Copyright © 2011-2022 走看看