zoukankan      html  css  js  c++  java
  • BZOJ 3530 数数

    题意:求(leq n)且不包含模式串集合(S)内的数作为子串的数的数量, 模式串总长,(nleq 10^3)

    明显可以在ac自动机上dp 算是常规,限制n就不说了。

    难题在于怎么处理前导0

    考虑先把(leq n-1)位的时候的(ans)算出来,这样就不存在前导0的问题了

    具体来说就是前导0的位填上也不会被统计。

    最后加上(n)位时候的答案就好了

    #include<cstdio>
    #include<cstring>
    #include<queue>
    const int mo = 1e9 + 7;
    const int N = 1e3 + 5e2 + 7;
    typedef long long ll;
    inline ll max(ll a, ll b) {return a > b ? a : b;}
    struct trie {int fail, end, sum, son[10];} t[N];
    int pcnt = 0;
    
    inline void ins() {
      char qs[N]; scanf ("%s", qs);
      int lens = strlen(qs), p = 0; //printf ("%d", lens);
      for (int i = 0; i < lens; i++) {
        if (!t[p].son[qs[i] - 48]) t[p].son[qs[i] - 48] = ++pcnt;
        p = t[p].son[qs[i] - 48];
      } t[p].end = 1;
    }
    inline void getfail() {
      std :: queue<int> q;
      for (int i = 0; i < 10; i++) if (t[0].son[i]) 
        q.push(t[0].son[i]), t[t[0].son[i]].fail = 0;
      while (!q.empty()) {
        int u = q.front(); q.pop();
        //printf ("%d ", t[1].fail);
        for (int i = 0; i < 10; i++) {
          if (t[u].son[i]) 
            t[t[u].son[i]].fail = t[t[u].fail].son[i], q.push(t[u].son[i]);
          else t[u].son[i] = t[t[u].fail].son[i];
        } t[u].end |= t[t[u].fail].end; 
      }
    } int m;
    int g[N][N], f[N][N][2];char s[N];ll ans = 0; char ss[N];
    int main() {
      scanf ("%s", s); scanf ("%d", &m);int up = strlen(s);
      while (m--) ins(); g[0][0] = 1; getfail();
      for (int i = 1; i <= up; i++) ss[i] = s[i - 1];
      int lens = up; //printf ("%d", pcnt);
      for (int i = 0; i < up; i++)
        for (int u = 0; u <= pcnt; u++) if (!t[u].end)
          for (int p = 0; p < 10; p++) if (!t[t[u].son[p]].end) {
            if (!i && !p) continue;
           // printf ("xxx");
            g[i + 1][t[u].son[p]] += g[i][u], g[i + 1][t[u].son[p]] %= mo;
          }
      for (int i = 1; i < lens; i++) 
        for (int j = 0; j <= pcnt; j++) ans = (ans + g[i][j]) % mo;
      f[0][0][1] = 1;// printf ("%lld
    ", ans);
      for (int i = 0; i < lens; i++) 
        for (int u = 0; u <= pcnt; u++) if (!t[u].end)
          for (int p = 0; p < 10; p++) if (!t[t[u].son[p]].end) {
            if (!i && !p) continue;
            f[i + 1][t[u].son[p]][0] = (f[i + 1][t[u].son[p]][0] + f[i][u][0]) % mo;
            if (p < ss[i + 1] - '0') 
              f[i + 1][t[u].son[p]][0] = (f[i + 1][t[u].son[p]][0] + f[i][u][1]) % mo;
            if (p == ss[i + 1] - '0')
              f[i + 1][t[u].son[p]][1] = (f[i + 1][t[u].son[p]][1] + f[i][u][1]) % mo;
          }
      for(int i = 0; i <= pcnt; ++i)
        ans = (ans + f[lens][i][0]) % mo, ans = (ans + f[lens][i][1]) % mo;
      printf ("%lld
    ", ans);
    }
    
  • 相关阅读:
    git init 后关联github仓库是发生错误:
    node mysql模块写入中文字符时的乱码问题
    Error: ER_BAD_FIELD_ERROR: Unknown column 'xxx' in 'where clause'
    安装MariaDB
    yum命令无效
    文档管理系统介绍
    RichTextBox文字处理控件属性介绍
    Android调用相册拍照控件实现系统控件缩放切割图片
    苹果5S指纹扫描识别传感器Touch ID有利于iPhone的安全性
    在服务器端将XML转换成HTML
  • 原文地址:https://www.cnblogs.com/cjc030205/p/11638082.html
Copyright © 2011-2022 走看看