• luogu 3281 数数


    (f[n])为串(s[1...n])的答案,(sdif[n])为串(s[1...n])有多少个不同的串

    假设串(n)的长度为(len[n]),现在在串(s[1...n])后面增加一个字符p

    考虑增加字符(p)后相较于原来的字符串多了哪些子串,

    明显是(s[1...n]+p,s[2...n]+p,s[3...n]+p,...,p)

    对原来答案增加的贡献是(newp = sdif[n]*B+(len[n]+1)*p),所以现在的答案是$ newp+lastans$;

    定义(S[n])(0+1+2+3+...+n)的和

    假设现在随便填(先考虑位数不足的情况)

    每个位置有(0~B-1)(B)种填法

    同时因为我们注意到了一共会有(B)种填法,对原来的(f[n])的答案转移时也应该$*B $

    所以对原来增加的贡献为(sum newp = B^2*sdif[n]+(len[n]+1)*S[B-1]);

    但是这是前面只有一种串的情况

    假设以(n)为结尾的有(sdif[n])种不同的串,

    那么实际贡献为(sum newp = B^2*suf[n]+sdif[n]*(len[n]+1)*S[B-1])

    现在考虑在串(s[1...n])加入一个字符(p)后,包含(p)的后缀的计算。

    对于不同的串的个数(sdif[n]),转移明显是(sdif[n]*B)

    接着把需要维护的东西放在数位dp上做。

    考虑维护以(i)为结尾的后缀和(prex_{i,0/1}),以(i)为结尾的串的答案(f_{i,0/1}),以(i)为结尾的不同的串的个数(sdif_{i,0/1})

    (0,1)分别是不卡/卡上界

    对于第一次dp,计算(len<n(m))的答案,明显是随便填;

    对于第二次dp,计算位数相等时的答案,对于卡不卡上界分类讨论

    (f_{i,0})有两种转移,一种是从上一次不卡上界的转移,那么这一位随便填,有(B)种填法

    另外一种是从上一次卡上界的转移,这一位只能填([0,a_i-1])一共(a_i)种填法,然后用后缀和更新

    (f_{i,1})同理,只能从(f_{i-1,1})转移,然后用后缀和更新。

    #include<cstdio>
    #include<cstring>
    const int N = 3e5+7;
    typedef long long LL;
    const long long p = 20130427;
    #define R register
    int B;
    LL S0[N], prex[N][2], sdif[N][2], f[N][2];
    inline int max(LL a, LL b) {
      return a > b ? a : b;
    }
    inline LL dp(LL *a, int len) {
      if (!len || (len == 1 && !a[1])) return 0;
      memset(prex, 0, sizeof(prex));
      memset(sdif, 0, sizeof (sdif));
      memset(f, 0, sizeof(f));
      LL ans = 0;
      if (len > 1) {
        sdif[1][0] = B - 1LL, prex[1][0] = S0[B - 1], f[1][0] = S0[B - 1];
        ans = (ans + f[1][0]) % p;
        for (R int i = 2; i < len; i++) {
          sdif[i][0] = (sdif[i - 1][0] * B % p) % p;
          prex[i][0] = (prex[i - 1][0] * B % p * B % p + S0[B - 1] * i % p * sdif[i - 1][0] % p) % p;
          f[i][0] = (f[i - 1][0] * B % p + prex[i][0]) % p;
          ans = (ans + f[i][0]) % p;
        }
      }
      memset(prex, 0, sizeof(prex));
      memset(sdif, 0, sizeof(sdif));
      memset(f, 0LL, sizeof(f));
      sdif[1][0] = max(a[1] - 1, 0);
      prex[1][0] = S0[max(a[1] - 1, 0)]; 
      f[1][0] = prex[1][0];
      sdif[1][1] = 1, prex[1][1] = a[1]; 
      f[1][1] = prex[1][1];
      for (R int i = 2; i <= len; i++) {
        sdif[i][0] = (sdif[i - 1][0] * B % p + sdif[i - 1][1] * a[i] % p) % p;
        sdif[i][1] = sdif[i - 1][1];
        prex[i][0] = (prex[i - 1][0] * B % p * B % p + sdif[i - 1][0] * S0[B - 1] % p * i % p
                      + prex[i - 1][1] * B % p * a[i] % p + sdif[i - 1][1] * S0[max(a[i] - 1, 0)] % p * i % p) % p;
        prex[i][1] = (prex[i - 1][1] * B % p + i % p * a[i] % p);
        f[i][0] = ((f[i - 1][0] * B % p) + (f[i - 1][1] * a[i] % p) + prex[i][0]) % p;
       
        f[i][1] = (f[i - 1][1] + prex[i][1]) % p;
      } 
      ans = (ans + f[len][0] + f[len][1]) % p;
      return ans;
    }
    LL A[N], Bx[N], tmp[N];
    int main() {
      LL x, y;
      scanf("%d", &B);
      for (R int i = 1; i <= B; i++) S0[i] = (S0[i - 1] + i) % p;
      int n, m;
      scanf("%d", &n);
      for (R int i = 1; i <= n; i++) scanf("%lld", &A[i]);
      for (R int i = n; i >= 1; i--) {
        if (A[i] > 0) {
          A[i]--;
          if (i == 1 && n != 1 && !A[i]) {
            for (R int j = 2; j <= n; j++)
              tmp[j - 1] = A[j];
            for (R int j = 1; j < n; j++)
              A[j] = tmp[j];
            n--;
          }
          break;
        }
        A[i] = B - 1LL;
    
      }
      scanf("%d", &m);
      for (R int i = 1; i <= m; i++) scanf("%lld", &Bx[i]);
      //printf("%lld %lld
    ", dp(Bx, m), dp(A, n));
      printf("%lld", ((dp(Bx, m) - dp(A, n)) % p + p) % p);
    }
    
    
  • 相关阅读:
    查询剩余存储空间
    1090. Highest Price in Supply Chain (25) -计层的BFS改进
    1079. Total Sales of Supply Chain (25) -记录层的BFS改进
    1076. Forwards on Weibo (30)
    1098. Insertion or Heap Sort (25)
    1077. Kuchiguse (20)
    (一二四)tableView的多组数据展示和手动排序
    1096. Consecutive Factors (20)
    (一二三)基于GCD的dispatch_once实现单例设计
    1084. Broken Keyboard (20)
  • 原文地址:https://www.cnblogs.com/cjc030205/p/11663537.html
Copyright © 2020-2023  润新知