P2336 [SCOI2012]喵星球上的点名

题目描述

a180285 幸运地被选做了地球到喵星球的留学生。他发现喵星人在上课前的点名现象非常有趣。

假设课堂上有 \(N\) 个喵星人,每个喵星人的名字由姓和名构成。喵星球上的老师会选择 \(M\) 个串来点名,每次读出一个串的时候,如果这个串是一个喵星人的姓或名的子串,那么这个喵星人就必须答到。

然而,由于喵星人的字码过于古怪,以至于不能用 ASCII 码来表示。为了方便描述,a180285 决定用数串来表示喵星人的名字。

现在你能帮助 a180285 统计每次点名的时候有多少喵星人答到,以及 \(M\) 次点名结束后每个喵星人答到多少次吗?

输入输出格式

输入格式:

现在定义喵星球上的字符串给定方法:

先给出一个正整数 \(L\) ,表示字符串的长度,接下来\(L\)个整数表示字符串的每个字符。

输入的第一行是两个整数 \(N\) 和 \(M\)。

接下来有 \(N\) 行, 每行包含第 \(i\) 个喵星人的姓和名两个串。 姓和名都是标准的喵星球上的字符串。

接下来有 \(M\) 行,每行包含一个喵星球上的字符串,表示老师点名的串。

输出格式:

对于每个老师点名的串输出有多少个喵星人应该答到。

然后在最后一行输出每个喵星人被点到多少次。

说明

\(n\le 5\times 10^4,m\le 10^5\),串总长\(\le 10^5\)


先建广义SAM

发现点名是子树问题,转换到dfs序

第一问就是区间求颜色数,第二问是统计每种颜色被多少区间覆盖。

用莫队就可以了,在新加入颜色和删去颜色的时候处理一下就行了。


Code:

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <algorithm>
  4. #include <map>
  5. const int N=2e5+10;
  6. std::map <int,int> ch[N];
  7. int col[N],par[N],len[N],las=1,tot=1,id;
  8. void extend(int c)
  9. {
  10. int now=++tot,p=las;
  11. len[now]=len[p]+1,col[now]=id;
  12. while(p&&!ch[p][c]) ch[p][c]=now,p=par[p];
  13. if(!p) par[now]=1;
  14. else
  15. {
  16. int x=ch[p][c];
  17. if(len[x]==len[p]+1) par[now]=x;
  18. else
  19. {
  20. int y=++tot;
  21. len[y]=len[p]+1,par[y]=par[x],col[y]=id,ch[y]=ch[x];
  22. while(p&&ch[p][c]==x) ch[p][c]=y,p=par[p];
  23. par[now]=par[x]=y;
  24. }
  25. }
  26. las=now;
  27. }
  28. int head[N],to[N],Next[N],cnt;
  29. void add(int u,int v)
  30. {
  31. to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
  32. }
  33. int dfn[N],low[N],ha[N],dfsclock,n,m,m_;
  34. void dfs(int now)
  35. {
  36. ha[dfn[now]=++dfsclock]=now;
  37. for(int i=head[now];i;i=Next[i]) dfs(to[i]);
  38. low[now]=dfsclock;
  39. }
  40. struct node
  41. {
  42. int id,l,r,fi;
  43. node(){}
  44. node(int id,int l,int r,int fi){this->id=id,this->l=l,this->r=r,this->fi=fi;}
  45. bool friend operator <(node a,node b){return a.fi==b.fi?a.l<b.l:a.fi<b.fi;}
  46. }q[N];
  47. int ans[N],sum[N],st[N],tax[N],su;
  48. void add(int p)
  49. {
  50. int c=col[ha[p]];
  51. if(!tax[c]) ++su,st[c]=id;
  52. ++tax[c];
  53. }
  54. void del(int p)
  55. {
  56. int c=col[ha[p]];
  57. --tax[c];
  58. if(!tax[c]) --su,sum[c]+=id-st[c];
  59. }
  60. int main()
  61. {
  62. scanf("%d%d",&n,&m);
  63. for(id=1;id<=n;id++)
  64. {
  65. int Len;las=1;
  66. scanf("%d",&Len);
  67. for(int c,i=1;i<=Len;i++) scanf("%d",&c),extend(c);
  68. las=1;scanf("%d",&Len);
  69. for(int c,i=1;i<=Len;i++) scanf("%d",&c),extend(c);
  70. }
  71. for(int i=2;i<=tot;i++) add(par[i],i);
  72. dfs(1);int B=sqrt(dfsclock)+1;
  73. for(int i=1;i<=m;i++)
  74. {
  75. int Len,now=1;
  76. scanf("%d",&Len);
  77. for(int c,j=1;j<=Len;j++)
  78. {
  79. scanf("%d",&c);
  80. now=ch[now][c];
  81. }
  82. if(now) q[++m_]=node(i,dfn[now],low[now],low[now]/B);
  83. }
  84. std::sort(q+1,q+1+m_);
  85. int l=q[1].l,r=l-1;
  86. for(id=1;id<=m_;id++)
  87. {
  88. while(q[id].l<l) add(--l);
  89. while(q[id].l>l) del(l++);
  90. while(q[id].r<r) del(r--);
  91. while(q[id].r>r) add(++r);
  92. ans[q[id].id]=su;
  93. }
  94. while(l<=r) del(l++);
  95. for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
  96. for(int i=1;i<=n;i++) printf("%d ",sum[i]);
  97. return 0;
  98. }

2019.1.10

洛谷 P2336 [SCOI2012]喵星球上的点名 解题报告的更多相关文章

  1. 洛谷P2336 [SCOI2012]喵星球上的点名(后缀数组+莫队)

    我学AC自动机的时候就看到了这题,想用AC自动机结果被学长码风劝退-- 学后缀数组时又看到了这题--那就写写后缀数组做法吧 结果码风貌似比当年劝退我的学长还毒瘤啊 对所有的模式串+询问串,不同串之间用 ...

  2. 洛咕 P2336 [SCOI2012]喵星球上的点名

    洛咕 P2336 [SCOI2012]喵星球上的点名 先求出SA和height,一个点名串对应的就是一段区间,还有很多个点,就转化成了 有很多个区间,很多个点集,对每个区间计算和多少个点集有交,对每个 ...

  3. [BZOJ2754] [SCOI2012]喵星球上的点名解题报告|后缀数组

    a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣.   假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串来点名,每次读出一个串的 ...

  4. P2336 [SCOI2012]喵星球上的点名(后缀自动机+莫队+dfs序)

    P2336 [SCOI2012]喵星球上的点名 名字怎么存?显然是后缀自动机辣 询问点到多少个喵喵喵其实就是 查询后缀自动机上parent树的一个子树 于是我们考虑莫队 怎么树上莫队呢 我们用dfs序 ...

  5. Luogu P2336 [SCOI2012]喵星球上的点名

    题目链接 \(Click Here\)_ \(200\)行纯干货的代码,一发\(WA\)掉真的是让人窒息,幸好最后找到了锅在哪.(差点就要弃掉了\(QAQ\)) [调出来的时候真的是要高兴到哭出来了\ ...

  6. P2336 [SCOI2012]喵星球上的点名(SA+莫队)

    题面传送门 一道还算有点含金量的 SA 罢-- 首先按照套路我们把读入的所有字符串都粘在一起,中间用分隔符隔开并建出后缀数组出来. 我们考虑对于一个固定的字符串 \(s\),什么样的字符串 \(t\) ...

  7. BZOJ 2754: [SCOI2012]喵星球上的点名 [后缀数组+暴力]

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1906  Solved: 839[Submit][St ...

  8. 【BZOJ2754】[SCOI2012]喵星球上的点名

    [BZOJ2754][SCOI2012]喵星球上的点名 题面 bzoj 洛谷 题解 这题有各种神仙做法啊,什么暴力\(AC\)自动机.\(SAM\)等等五花八门 我这个蒟蒻在这里提供一种复杂度正确且常 ...

  9. BZOJ 2754: [SCOI2012]喵星球上的点名

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 649  Solved: 305[Submit][Sta ...

随机推荐

  1. UML类图(Unified Modeling Language Class Diagrams)

    统一建模语言(UML) |  类图 什么是UML? UML是一种用于可视化描述系统,具有广泛用途的建模语言.作为一种标准化的图形语言,在软件工业中被用于软件系统部件的具体化,可视化,结构化描述以及撰写 ...

  2. 20155306 白皎 0day漏洞——漏洞的复现

    一.Ubuntu16.04 (CVE-2017-16995) 1.漏洞概述 Ubuntu最新版本16.04存在本地提权漏洞,该漏洞存在于Linux内核带有的eBPF bpf(2)系统调用中,当用户提供 ...

  3. WPF编程,将控件所呈现的内容保存成图像的一种方法。

    原文:WPF编程,将控件所呈现的内容保存成图像的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/detai ...

  4. HW 2017 12 17可禾大佬神题

    好不容易搞来的题目,不写一写怎么行呢. 不过难度真心不高(一小时K掉),都是老题+暴力题,没有欧洲玄学. 再说一句,这试卷是叶可禾出的吧. T1 好老的题目,看到有多组数据我还怕了,以为有更流弊的算法 ...

  5. 谈谈对Python装饰器的理解

    装饰器,又名函数修饰符.笔者觉得函数修饰符,这个名字更能直观的反应他的作用. 函数修饰符语法特征 :         @ + 修饰符 函数修饰符的装饰对象:        函数修饰符,就是说他修饰的是 ...

  6. Hadoop日记Day15---MapReduce新旧api的比较

    我使用hadoop的是hadoop1.1.2,而很多公司也在使用hadoop0.2x版本,因此市面上的hadoop资料版本不一,为了扩充自己的知识面,MapReduce的新旧api进行了比较研究. h ...

  7. Linux 学习日记 1

    这是我第一次系统地学习Linux,希望通过这个学习日记收获一些东西把-- @_@ Grub - 启动管理器   在启动时让用户选择要启动的系统.(但是windows比较霸道--重装windows后会将 ...

  8. java.lang.IllegalStateException: Cannot forward after response has been committe

    参考:https://blog.csdn.net/lewky_liu/article/details/79845655 加上 return 搞定

  9. effective c++ 笔记 (13-17)

    //---------------------------15/03/30---------------------------- //#13   以对象管理资源 { void f() { Inves ...

  10. python3 subprocess模块

    当我们在执行python程序的时候想要执行系统shell可以使用subprocess,这时可以新起一个进程来执行系统的shell命令,python3常用的有subprocess.run()和subpr ...