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, s
evenk felt angry and began to check oimaster's online talk with ChuYuXun.    Oimaster talked with Ch
uYuXun 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

解题思路:

利用Parent树的子节点都是父节点母串的性质,在大串的每个实节点打上标记,然后构建出这颗Parent树。

那么我们的问题就变成了在一个Fail节点子树内不同颜色个数。

像不像HH的项链?

把Dfs序构建出来,离线树状数组就好了。

代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. const int N=;
  5. const int M=;
  6. struct sant{
  7. int tranc[];
  8. int len;
  9. int pre;
  10. }s[N];
  11. struct pnt{
  12. int hd;
  13. int col;
  14. int ind;
  15. int oud;
  16. }p[N];
  17. struct ent{
  18. int twd;
  19. int lst;
  20. }e[N];
  21. struct qust{
  22. int l,r;
  23. int ans;
  24. int no;
  25. }q[N];
  26. int siz;
  27. int fin;
  28. int n,Q;
  29. int cnt;
  30. int dfn;
  31. char tmp[N];
  32. int line[N];
  33. int lst[N];
  34. int phr[N];
  35. int col[N];
  36. void Insert(int c,int whic)
  37. {
  38. int nwp,nwq,lsp,lsq;
  39. nwp=++siz;
  40. p[nwp].col=whic;
  41. s[nwp].len=s[fin].len+;
  42. for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
  43. s[lsp].tranc[c]=nwp;
  44. if(!lsp)
  45. s[nwp].pre=;
  46. else{
  47. lsq=s[lsp].tranc[c];
  48. if(s[lsq].len==s[lsp].len+)
  49. s[nwp].pre=lsq;
  50. else{
  51. nwq=++siz;
  52. s[nwq]=s[lsq];
  53. s[nwq].len=s[lsp].len+;
  54. s[nwp].pre=s[lsq].pre=nwq;
  55. while(s[lsp].tranc[c]==lsq)
  56. {
  57. s[lsp].tranc[c]=nwq;
  58. lsp=s[lsp].pre;
  59. }
  60. }
  61. }
  62. fin=nwp;
  63. return ;
  64. }
  65. void ade(int f,int t)
  66. {
  67. cnt++;
  68. e[cnt].twd=t;
  69. e[cnt].lst=p[f].hd;
  70. p[f].hd=cnt;
  71. return ;
  72. }
  73. void Dfs(int x)
  74. {
  75. p[x].ind=++dfn;
  76. phr[dfn]=x;
  77. col[dfn]=p[x].col;
  78. for(int i=p[x].hd;i;i=e[i].lst)
  79. {
  80. int to=e[i].twd;
  81. Dfs(to);
  82. }
  83. p[x].oud=dfn;
  84. return ;
  85. }
  86. bool cmp(qust x,qust y)
  87. {
  88. return x.r<y.r;
  89. }
  90. bool cmq(qust x,qust y)
  91. {
  92. return x.no<y.no;
  93. }
  94. int lowbit(int x)
  95. {
  96. return x&(-x);
  97. }
  98. void update(int pos,int x)
  99. {
  100. while(pos&&pos<=siz)
  101. {
  102. line[pos]+=x;
  103. pos+=lowbit(pos);
  104. }
  105. return ;
  106. }
  107. int query(int pos)
  108. {
  109. int ans=;
  110. while(pos)
  111. {
  112. ans+=line[pos];
  113. pos-=lowbit(pos);
  114. }
  115. return ans;
  116. }
  117. int main()
  118. {
  119. fin=++siz;
  120. scanf("%d%d",&n,&Q);
  121. for(int i=;i<=n;i++)
  122. {
  123. scanf("%s",tmp+);
  124. fin=;
  125. int len=strlen(tmp+);
  126. for(int j=;j<=len;j++)
  127. Insert(tmp[j]-'a',i);
  128. }
  129. for(int i=;i<=siz;i++)
  130. ade(s[i].pre,i);
  131. Dfs();
  132.  
  133. for(int i=;i<=Q;i++)
  134. {
  135. scanf("%s",tmp+);
  136. int root=;
  137. int len=strlen(tmp+);
  138. for(int j=;j<=len;j++)
  139. root=s[root].tranc[tmp[j]-'a'];
  140. q[i].no=i;
  141. if(!root)
  142. continue;
  143. q[i].l=p[root].ind;
  144. q[i].r=p[root].oud;
  145. }
  146. std::sort(q+,q+Q+,cmp);
  147. int rr=;
  148. for(int i=;i<=Q;i++)
  149. {
  150. while(rr<=q[i].r)
  151. {
  152. if(!col[rr])
  153. {
  154. rr++;
  155. continue;
  156. }
  157. if(lst[col[rr]])
  158. update(lst[col[rr]],-);
  159. update(rr,);
  160. lst[col[rr]]=rr;
  161. rr++;
  162. }
  163. rr--;
  164. if(!q[i].l)
  165. continue;
  166. q[i].ans=query(q[i].r)-query(q[i].l-);
  167. }
  168. std::sort(q+,q+Q+,cmq);
  169. for(int i=;i<=Q;i++)
  170. printf("%d\n",q[i].ans);
  171. return ;
  172. }

BZOJ2780: [Spoj]8093 Sevenk Love Oimaster(广义后缀自动机,Parent树,Dfs序)的更多相关文章

  1. 【BZOJ2780】[Spoj]8093 Sevenk Love Oimaster 广义后缀自动机

    [BZOJ2780][Spoj]8093 Sevenk Love Oimaster Description Oimaster and sevenk love each other.     But r ...

  2. BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster [广义后缀自动机]

    JZPGYZ - Sevenk Love Oimaster     Oimaster and sevenk love each other.       But recently,sevenk hea ...

  3. bzoj 3277 串 && bzoj 3473 字符串 && bzoj 2780 [Spoj]8093 Sevenk Love Oimaster——广义后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3277 https://www.lydsy.com/JudgeOnline/problem.p ...

  4. BZOJ 2780 [Spoj]8093 Sevenk Love Oimaster ——广义后缀自动机

    给定n个串m个询问,问每个串在n个串多少个串中出现了. 构建广义后缀自动机,(就是把所有字符串的后缀自动机合并起来)其实只需要add的时候注意一下就可以了. 然后对于每一个串,跑一边匹配,到达了now ...

  5. 【BZOJ2780】【SPOJ】Sevenk Love Oimaster(后缀自动机)

    [BZOJ2780][SPOJ]Sevenk Love Oimaster(后缀自动机) 题面 BZOJ 洛谷 题解 裸的广义后缀自动机??? 建立广义后缀自动机建立出来之后算一下每个节点被几个串给包括 ...

  6. BZOJ2780 [Spoj]8093 Sevenk Love Oimaster 【广义后缀自动机】

    题目 Oimaster and sevenk love each other. But recently,sevenk heard that a girl named ChuYuXun was dat ...

  7. BZOJ.2780.[SPOJ8093]Sevenk Love Oimaster(广义后缀自动机)

    题目链接 \(Description\) 给定n个模式串,多次询问一个串在多少个模式串中出现过.(字符集为26个小写字母) \(Solution\) 对每个询问串进行匹配最终会达到一个节点,我们需要得 ...

  8. SP8093 JZPGYZ - Sevenk Love Oimaster(广义后缀自动机)

    题意 题目链接 Sol 广义后缀自动机板子题..和BZOJ串那个题很像 首先建出询问串的SAM,然后统计一下每个节点被多少个串包含 最后直接拿询问串上去跑就行了 #include<bits/st ...

  9. BZOJ2780——[Spoj]8093 Sevenk Love Oimaster

    0.题意:给定N个原始字符串S,M次查询某个特殊的字符串S'在多少个原始串中出现过. 1.分析:这个题我们第一感觉就是可以用后缀自动机来搞,然后我们发现不是本质不同的字串..求出现过的次数,也就是说多 ...

随机推荐

  1. 受不了Android SDK文档打开缓慢问题,自己开发简易脱机浏览器。

    google android sdk离线文档打开的时候特别慢,据说是要从谷歌官网拉取一些东西导致的.脱机浏览能够解决该问题.PC端能够使用firefox. 可是Android端貌似没有支持脱机工作的浏 ...

  2. 我持续推动Rust语言支持Windows XP系统

    前言 Rust好像长期以来不支持Windows XP系统.有不少用户发帖提议官方支持XP,基本上都被Rust官方开发人员明白的拒绝了.他们的对话大致上是以这种形式開始和结束的(当中乙方代表官方及其拥趸 ...

  3. 怎样安装Windows7操作系统

     1. 打开电脑,插入Windows7安装光盘. 2. 又一次启动电脑: 3. 依据提示按下对应的键.进入选择启动项菜单选择光驱引导.在"Boot Menu"界面按键盘上下键选 ...

  4. js易错点总结及 常见面试的坑

    最近在研究Javascript发现了其中一些比较灵异的事情.有点让人感到无语比如: var arr = [], arr2 = {}; console.log(typeof(arr) === typeo ...

  5. TwinCAT 3中基于UDP协议通讯的C++实现

    因为项目需要,学习了TwinCAT3中使用UDP协议进行通讯的基本知识.这个做个简单的笔记,方便以后查询. 1 概述 倍福为了实现从实时环境中直接访问网卡(network cards)专门提供了一个函 ...

  6. SQL 查找存在某内容的存储过程

    --查找存在某表名的存储过程 SELECT distinct b.name from syscomments a,sysobjects b WHERE a.id=b.id and a.TEXT LIK ...

  7. python 批量下载文件

    file.txt 的内容为: http://183.xxx.xxx.54:188/my/qqq.ico::qq.exe::0::http://183.xxx.xxx.54:186/my/ddnf.ic ...

  8. SpringMVC与SpringBoot返回静态页面遇到的问题

    1.SpringMVC静态页面响应 package com.sv.controller; import org.springframework.stereotype.Controller; impor ...

  9. Python之路:画空心矩形

    1.if语句中当要判断多个语句成立才能执行语句时候,可以用or(或,只要其中一个成立就可以执行下一条语句)或者and(只要有其中一个不成立就不会执行下一条语句) 2.在Python中range函数会产 ...

  10. CSUOJ 1638 Continued Fraction

    1638: Continued Fraction Time Limit: 1 Sec  Memory Limit: 128 MB Description Input Output Sample Inp ...