zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    我的知识库(4) java获取页面编码(Z)
    知识库(3)JAVA 正则表达式 (超详细)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts
    某人总结的《英语听力的技巧 》,挺搞的
    我的知识库(5)java单例模式详解
    构建可扩展程序
    SerialPort (RS232 Serial COM Port) in C# .NET
    Python学习笔记——String、Sequences
    UI题目我的答案
    jQuery学习系列学会操纵Form表单元素(1)
  • 原文地址:https://www.cnblogs.com/refun/p/10016679.html
Copyright © 2011-2022 走看看