• 作词(write)


    题目描述

    lovelive预赛要求原创歌曲,所以小海要准备新歌的词。小海有一段模板串ai,长度为n,她可以在模板串中选择一个区间的子串来作为歌词。但是已经有m个区间[li,ri]的子串被当做歌词了。为了保证原创,小海这次选出来的子串中不能出现之前给出的m个子串。小海想知道有多少可行的区间可以选择。

    输入

    第一行2个数 n,m

    第二行一个字符串ai

    接下来m行,每行两个数li,ri

    输出

    一个数表示答案

    样例输入

    6 2
    aabaac
    2 3
    5 6
    

    样例输出

    10

    提示

    数据范围:

    20% n,m<=100

    另外20% ri-li<=10

    另外 20% sigma ri-li<=n

    另外0% 没有两个已被选出的子串互相包含

    100% n,m<=3e5

    考虑以$i$为结尾的串,合法的左端点都是一段连续的区间,形如$[l,i-1]$

    令$f[i]=l$

    那么考虑一段区间$[l,r]$,它会对所有包含他的后缀$b$的$f[b]$产生$b-(r-l+1)+1+1$的贡献。

    注意贡献要取$max$,另外有$f[i]=max(f[i],f[i-1])$。

    用后缀自动机来干这个事情就行了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define M 600010
      4 #define LL long long
      5 #define inf 1047483647
      6 int tranc[M][27];
      7 int len[M], fa[M];
      8 int ri[M];
      9 int cnt = 1, tail = 1;
     10 int c[M], od[M];
     11 int ft[M][20];
     12 int mn[M];
     13 int wh[M];
     14 struct Edge{
     15     int u, v, Next;
     16 } G[M];
     17 int head[M], tot;
     18 inline void add(int u, int v) {
     19     G[++ tot] = (Edge){u, v, head[u]};
     20     head[u] = tot;
     21 }
     22 inline void insert(int k) {
     23     int p = tail, np = ++ cnt, q, nq;
     24     len[np] = len[p] + 1;
     25     ri[np] = 1;
     26     for(; p && !tranc[p][k]; p = fa[p]) {
     27         tranc[p][k] = np;
     28     }
     29     if(!p) fa[np] = 1;
     30     else {
     31         q = tranc[p][k];
     32         if(len[q] == len[p] + 1) fa[np] = q;
     33         else {
     34             fa[nq = ++ cnt] = fa[q];
     35             memcpy(tranc[nq], tranc[q], sizeof(tranc[q]));
     36             fa[q] = fa[np] = nq;
     37             len[nq] = len[p] + 1;
     38             for(; tranc[p][k] == q; p = fa[p]) {
     39                 tranc[p][k] = nq;
     40             }
     41         }
     42     }
     43     tail = np;
     44 }
     45 inline void init(int m) {
     46     for(int i = 1; i <= cnt; ++ i) c[len[i]] ++, mn[i] = inf;
     47     for(int i = 1; i <= m; ++ i) c[i] += c[i - 1];
     48     for(int i = cnt; i >= 1; -- i) od[c[len[i]] --] = i;
     49     for(int i = cnt; i >= 1; -- i) {
     50         ri[fa[od[i]]] += ri[od[i]];
     51     }
     52     memset(head, -1, sizeof(head));
     53     for(int i = 2; i <= cnt; ++ i) {
     54         add(fa[i], i);
     55         ft[i][0] = fa[i];
     56     }
     57     for(int i = 1; i <= 19; ++ i) {
     58         for(int j = 1; j <= cnt; ++ j) {
     59             ft[j][i] = ft[ft[j][i - 1]][i - 1];
     60         }
     61     }
     62 }
     63 int L[M], R[M], id[M];
     64 int dfs_clock, f[M], h[M];
     65 inline void dfs(int x, int g) {
     66     id[L[x] = ++ dfs_clock] = x;
     67     int j = g;
     68     if(mn[x] != inf) j = 1; 
     69     for(int i = head[x]; i != -1; i = G[i].Next) {
     70         dfs(G[i].v, j);
     71     }
     72     R[x] = dfs_clock;
     73     if(!g && j) {
     74         for(int i = L[x]; i <= R[x]; ++ i) {
     75             int b = h[id[i]]; 
     76             if(b) f[b] = max(f[b], b - mn[x] + 2);
     77         } 
     78     }
     79 }
     80 char s[M];
     81 int main() {
     82     int n, m;
     83     scanf("%d%d", &n, &m);
     84     scanf("%s", s + 1);
     85     for(int i = 1; i <= n; ++ i) {
     86         insert(s[i] - 'a');
     87         wh[i] = tail; 
     88         h[tail] = i;
     89     }
     90     init(cnt);
     91     for(int i = 1; i <= m; ++ i) {
     92         int l, r;
     93         scanf("%d%d", &l, &r);
     94         int o = wh[r];
     95         for(int j = 19; j >= 0; -- j) {
     96             if(len[ft[o][j]] >= r - l + 1) {
     97                 o = ft[o][j];
     98             }
     99         }
    100         mn[o] = min(mn[o], r - l + 1);
    101     }
    102     for(int i = 1; i <= n; ++ i) f[i] = 1;
    103     dfs(1, 0);
    104     LL Ans = 0;
    105     for(int i = 1; i <= n; ++ i) {
    106         Ans += i - f[i] + 1;
    107         f[i + 1] = max(f[i + 1], f[i]);
    108     }
    109     printf("%lld
    ", Ans);
    110 }
  • 相关阅读:
    struts2 的特征
    The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory
    web.xml 404 500 配置
    重大发现 springmvc Controller 高级接收参数用法
    struts2 file
    struts2-core-2.3.20.jar
    系统设计工具
    Java基础
    IAM
    秒杀系统
  • 原文地址:https://www.cnblogs.com/iamqzh233/p/9445726.html
Copyright © 2020-2023  润新知