zoukankan      html  css  js  c++  java
  • [BZOJ3277]串 广义后缀自动机

    3277: 串

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 811  Solved: 329
    [Submit][Status][Discuss]

    Description

    字符串是oi界常考的问题。现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中
    至少k个字符串的子串(注意包括本身)。

    Input

    第一行两个整数n,k。
    接下来n行每行一个字符串。
    n,k,l<=100000

    Output

    输出一行n个整数,第i个整数表示第i个字符串的答案。

    Sample Input

    3 1
    abc
    a
    ab

    Sample Output

    6 1 3

    HINT

     

    Source

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<cstdio>
     7 #define maxn 200005
     8 using namespace std;
     9 int n,k;
    10 long long c[maxn];
    11 long long ans[maxn]; 
    12 struct data {
    13     long long son[maxn][26],link[maxn],step[maxn],last,cnt,t[maxn],size[maxn],tp[maxn];
    14     data() {last=cnt=1;}
    15     void extend(int x,int id) {
    16         int p=last,np=last=++cnt;step[np]=step[p]+1;t[np]=id;
    17         while(p&&!son[p][x]) son[p][x]=np,p=link[p];
    18         if(!p) link[np]=1;
    19         else {
    20             int q=son[p][x];
    21             if(step[q]==step[p]+1) link[np]=q;
    22             else {
    23                 int nq=++cnt;
    24                 memcpy(son[nq],son[q],sizeof(son[q]));
    25                 step[nq]=step[p]+1;
    26                 link[nq]=link[q];link[np]=link[q]=nq;size[nq]=size[q];tp[nq]=tp[q];
    27                 while(p&&son[p][x]==q) son[p][x]=nq,p=link[p];
    28             }
    29         }
    30         for(int i=np;i&&tp[i]!=id;i=link[i]) size[i]++,tp[i]=id;
    31     }
    32 }sam;
    33 int head[maxn],sum;
    34 struct edge {
    35     int to,next;
    36 }e[maxn];
    37 void add(int u,int v) {e[sum].to=v;e[sum].next=head[u];head[u]=sum++;}
    38 char s[maxn];
    39 void dfs(int x) {
    40     c[x]+=c[sam.link[x]];ans[sam.t[x]]+=c[x];
    41     for(int i=head[x];i>=0;i=e[i].next) dfs(e[i].to);
    42 }
    43 int main() {
    44     memset(head,-1,sizeof(head));
    45     scanf("%d%d",&n,&k);
    46     for(int i=1;i<=n;i++) {
    47         scanf("%s",s+1);
    48         int len=strlen(s+1);sam.last=1;
    49         for(int j=1;j<=len;j++) sam.extend(s[j]-'a',i);
    50     }
    51     for(int i=2;i<=sam.cnt;i++)    {
    52         add(sam.link[i],i);
    53         if(sam.size[i]>=k) c[i]=sam.step[i]-sam.step[sam.link[i]];
    54     }
    55     dfs(1);
    56     for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
    57 }
    58 /*
    59 3 2
    60 abaac
    61 bba
    62 bbacb
    63 */
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    jq 换图片路径
    sql 把一列的数据按逗号分隔转换成多行
    sql 数据库查看主外键关联
    sql 表连接 join
    sql 查看 锁定的表 或者 未提交 的事务
    WMI技术介绍和应用——查询硬件信息
    System.Web.HttpContext.Current.Server.MapPath("~/upload/SH") 未将对象引用设置为实例对象
    sql server output用法说明
    merge into 的用法
    JAVA Stop The World 第八节
  • 原文地址:https://www.cnblogs.com/wls001/p/8474695.html
Copyright © 2011-2022 走看看