• BZOJ2780:[SPOJ8093]Sevenk Love Oimaster(广义SAM)


    Description

    Oimaster and sevenk love each other.
    But recently,sevenk heard that a girl named ChuYuXun was dating with oimaster.As a woman's nature, sevenk felt angry and began to check oimaster's online talk with ChuYuXun.    
    Oimaster talked with ChuYuXun n times, and each online talk actually is a string.Sevenk asks q questions like this,    "how many strings in oimaster's online talk contain this string as their substrings?"
    有n个大串和m个询问,每次给出一个字符串s询问在多少个大串中出现过

    Input

    There are two integers in the first line, 
    the number of strings n and the number of questions q.
    And n lines follow, each of them is a string describing oimaster's online talk. 
    And q lines follow, each of them is a question.
    n<=10000, q<=60000 
    the total length of n strings<=100000, 
    the total length of q question strings<=360000

    Output

    For each question, output the answer in one line.

    Sample Input

    3 3
    abcabcabc
    aaa
    aafe
    abc
    a
    ca

    Sample Output

    1
    3
    1

    Solution

    先把大串的广义$SAM$建出来,然后用$n$个大串在$SAM$上跑。每个点开一个$vis[i]$和$size[i]$,存这个点上一次被哪个大串访问,这个点一共被几个大串访问过。

    同时每访问一个点,就要沿着这个点的$fa$指针往上暴跳,更新$vis$,同时$size+1$。直到跳到一个$vis$是当前大串的点就停止。

    答案就是用询问串在$SAM$上跑,终点的$size$值。

    还有一个$nlogn$的做法我不会QAQ

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define N (201000)
     5 using namespace std;
     6 
     7 int n,m,l[N],r[N];
     8 char s[N<<2],t[N<<1];
     9 
    10 struct SAM
    11 {
    12     int son[N][28],fa[N],step[N],size[N],vis[N];
    13     int p,q,np,nq,last,cnt;
    14     SAM(){last=cnt=1;}
    15 
    16     void Insert(int x)
    17     {
    18         p=last; np=last=++cnt; step[np]=step[p]+1;
    19         while (p && !son[p][x]) son[p][x]=np, p=fa[p];
    20         if (!p) fa[np]=1;
    21         else
    22         {
    23             q=son[p][x];
    24             if (step[q]==step[p]+1) fa[np]=q;
    25             else
    26             {
    27                 nq=++cnt; step[nq]=step[p]+1;
    28                 memcpy(son[nq],son[q],sizeof(son[q]));
    29                 fa[nq]=fa[q]; fa[q]=fa[np]=nq;
    30                 while (son[p][x]==q) son[p][x]=nq,p=fa[p];
    31             }
    32         }
    33     }
    34     void Calc()
    35     {
    36         for (int i=1; i<=n; ++i)
    37         {
    38             int now=1;
    39             for (int j=l[i]; j<r[i]; ++j)
    40             {
    41                 now=son[now][s[j]-'a'];
    42                 int t=now;
    43                 while (t && vis[t]!=i) vis[t]=i,++size[t],t=fa[t];
    44             }
    45         }
    46     }
    47     void Find(char s[])
    48     {
    49         int now=1;
    50         for (int j=0,l=strlen(s); j<l; ++j)
    51             now=son[now][s[j]-'a'];
    52         printf("%d
    ",size[now]);
    53     }
    54 }SAM;
    55 
    56 int main()
    57 {
    58     scanf("%d%d",&n,&m);
    59     for (int i=1; i<=n; ++i)
    60     {
    61         scanf("%s",s+r[i-1]); int len=strlen(s+r[i-1]);
    62         l[i]=r[i-1], r[i]=l[i]+len;
    63     }
    64     for (int i=1; i<=n; ++i,SAM.last=1)
    65         for (int j=l[i]; j<r[i]; ++j)
    66             SAM.Insert(s[j]-'a');
    67     SAM.Calc();
    68     for (int i=1; i<=m; ++i)
    69         scanf("%s",t),SAM.Find(t);
    70 }
  • 相关阅读:
    JS判断是PC端还是移动端
    js对象转数组
    js获取当前域名、Url、相对路径和参数以及指定参数
    javascript返回上一页的三种写法
    js正则归纳总结
    higtcharts 生成图表个数问题
    js如何处理后台传递过来的Map
    jQuey实现鼠标滑过整行变色
    <display:column>常用属性解释
    <display:table>常用属性解释
  • 原文地址:https://www.cnblogs.com/refun/p/10016679.html
Copyright © 2020-2023  润新知