题目大意:

给一个字符串,多次询问k个后缀,求它们两两间LCP长度总和

分析:

转化为后缀树,用虚树求

注意:

后缀树中代表后缀的点都是叶子节点

题目中取模并没有卵用

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <cctype>
  7. using namespace std;
  8. typedef long long LL;
  9. const int M=1000007;
  10. inline int rd(){
  11. int x=0;bool f=1;char c=getchar();
  12. for(;!isdigit(c);c=getchar())if(c=='-')f=0;
  13. for(;isdigit(c);c=getchar()) x=x*10+c-48;
  14. return f?x:-x;
  15. }
  16. int n,m;
  17. char s[M];
  18. int ch[M][26];
  19. int pre[M];
  20. LL len[M],sz[M];
  21. int last=1,tot=1;
  22. int g[M],te,hd[M],td;
  23. struct edge{int y,next;}e[M],dw[M];
  24. int dfn[M],tdfn;
  25. LL ans;
  26. int ln[M<<1],pos[M],T;
  27. int a[M<<1][23];
  28. int que[M*3];
  29. int st[M],cnt;
  30. int id[M];
  31. void addedge(int x,int y){
  32. e[++te].y=y;
  33. e[te].next=g[x];
  34. g[x]=te;
  35. }
  36. void addlink(int x,int y){
  37. if(x==y) return ;
  38. dw[++td].y=y;
  39. dw[td].next=hd[x];
  40. hd[x]=td;
  41. }
  42. int newnode(int x){
  43. ++tot;
  44. len[tot]=x;
  45. return tot;
  46. }
  47. void Sam(int x){
  48. int p,q,np,nq;
  49. p=last;
  50. last=np=newnode(len[last]+1);
  51. for(;p&&!ch[p][x];p=pre[p]) ch[p][x]=np;
  52. if(!p) pre[np]=1;
  53. else{
  54. q=ch[p][x];
  55. if(len[q]==len[p]+1) pre[np]=q;
  56. else{
  57. nq=newnode(len[p]+1);
  58. for(int i=0;i<26;i++) ch[nq][i]=ch[q][i];
  59. pre[nq]=pre[q];
  60. pre[q]=pre[np]=nq;
  61. for(;p&&ch[p][x]==q;p=pre[p]) ch[p][x]=nq;
  62. }
  63. }
  64. }
  65. void dfs(int x){
  66. dfn[x]=++tdfn;
  67. a[pos[x]=++T][0]=x;
  68. int p,y;
  69. for(p=g[x];p;p=e[p].next){
  70. y=e[p].y;
  71. dfs(y);
  72. a[++T][0]=x;
  73. }
  74. }
  75. int mn(int x,int y){
  76. return dfn[x]<dfn[y]?x:y;
  77. }
  78. void init(){
  79. int i,j,l;
  80. for(i=2;i<=T;i++) ln[i]=ln[i>>1]+1;
  81. for(i=T;i>0;i--){
  82. l=ln[T-i+1];
  83. for(j=1;j<=l;j++)
  84. a[i][j]=mn(a[i][j-1],a[i+(1<<j-1)][j-1]);
  85. }
  86. }
  87. int LCA(int x,int y){
  88. x=pos[x],y=pos[y];
  89. if(x>y)swap(x,y);
  90. int l=ln[y-x+1];
  91. return mn(a[x][l],a[y-(1<<l)+1][l]);
  92. }
  93. bool cmp(int x,int y){return dfn[x]<dfn[y];}
  94. void vbuild(int z){
  95. int i,x,anc;
  96. sort(que+1,que+z+1,cmp);
  97. z=unique(que+1,que+z+1)-(que+1);
  98. for(i=1;i<z;i++){
  99. x=LCA(que[i],que[i+1]);
  100. hd[x]=0; sz[x]=0;
  101. }
  102. hd[1]=0; sz[1]=0;
  103. for(i=1;i<=z;i++){
  104. x=que[i];
  105. hd[x]=0; sz[x]=1;
  106. }
  107. td=cnt=0;
  108. st[++cnt]=1;
  109. for(i=1;i<=z;i++){
  110. x=que[i];
  111. anc=LCA(x,st[cnt]);
  112. if(anc==st[cnt]) st[++cnt]=x;
  113. else{
  114. while(cnt>1 && anc==LCA(st[cnt-1],x)){
  115. addlink(st[cnt-1],st[cnt]);
  116. cnt--;
  117. }
  118. addlink(anc,st[cnt]);
  119. st[cnt]=anc;
  120. st[++cnt]=x;
  121. }
  122. }
  123. for(i=1;i<cnt;i++) addlink(st[i],st[i+1]);
  124. }
  125. void dp(int x){
  126. int p,y;
  127. for(p=hd[x];p;p=dw[p].next){
  128. y=dw[p].y;
  129. dp(y);
  130. ans+=(sz[x]*sz[y])*len[x];
  131. sz[x]+=sz[y];
  132. }
  133. }
  134. int main(){
  135. int i,z;
  136. n=rd();m=rd();
  137. scanf("%s",s+1);
  138. for(i=n;i>0;i--){
  139. Sam(s[i]-'a');
  140. id[i]=last;
  141. }
  142. for(i=2;i<=tot;i++) addedge(pre[i],i);
  143. dfs(1);
  144. init();
  145. while(m--){
  146. z=rd();
  147. for(i=1;i<=z;i++) que[i]=id[rd()];
  148. vbuild(z);
  149. ans=0;
  150. dp(1);
  151. printf("%lld\n",ans);
  152. }
  153. return 0;
  154. }

bzoj 3879 虚树的更多相关文章

  1. bzoj 2286(虚树+树形dp) 虚树模板

    树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5002  Sol ...

  2. BZOJ 3879: SvT [虚树 后缀树]

    传送门 题意: 多次询问,给出一些后缀,求两两之间$LCP$之和 哈哈哈哈哈哈哈竟然$1A$了,刚才还在想如果写不好这道题下节数学就不上了,看来是上天让我上数学课啊 $Suffix\ Virtual\ ...

  3. BZOJ 3879: SvT 虚树 + 后缀自动机

    Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始 ...

  4. BZOJ.5287.[AHOI HNOI2018]毒瘤(虚树 树形DP)

    BZOJ LOJ 洛谷 设\(f[i][0/1]\)表示到第\(i\)个点,不选/选这个点的方案数.对于一棵树,有:\[f[x][0]=\prod_{v\in son[x]}(f[v][0]+f[v] ...

  5. BZOJ.2286.[SDOI2011]消耗战(虚树 树形DP)

    题目链接 BZOJ 洛谷P2495 树形DP,对于每棵子树要么逐个删除其中要删除的边,要么直接断连向父节点的边. 如果当前点需要删除,那么直接断不需要再管子树. 复杂度O(m*n). 对于两个要删除的 ...

  6. Bzoj 2286 & Luogu P2495 消耗战(LCA+虚树+欧拉序)

    题面 洛谷 Bzoj 题解 很容易想到$O(nk)$的树形$dp$吧,设$f[i]$表示处理完这$i$颗子树的最小花费,同时再设一个$mi[i]$表示$i$到根节点$1$路径上的距离最小值.于是有: ...

  7. BZOJ 3572 [HNOI2014]世界树 (虚树+DP)

    题面:BZOJ传送门 洛谷传送门 题目大意:略 细节贼多的虚树$DP$ 先考虑只有一次询问的情况 一个节点$x$可能被它子树内的一个到x距离最小的特殊点管辖,还可能被管辖fa[x]的特殊点管辖 跑两次 ...

  8. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  9. BZOJ 2286 树链剖分+DFS序+虚树+树形DP

    第一次学习虚树,就是把无关的点去掉.S里维护一条链即可. #include <iostream> #include <cstring> #include <cstdio& ...

随机推荐

  1. Server对象(是属性)

    html, body { font-size: 10.5pt; } body { font-family: 微软雅黑, Helvetica, "Hiragino Sans GB", ...

  2. php之PDO使用【转载】

    <?php $dbh = new PDO('mysql:host=localhost;dbname=access_control', 'root', ''); $dbh->setAttri ...

  3. MySQL事件【转载】

    在系统管理或者数据库管理中,经常要周期性的执行某一个命令或者SQL语句.对于linux系统熟悉的人都知道linux的cron计划任务,能很方便地实现定期运行指定命令的功能.Mysql在5.1以后推出了 ...

  4. MyBatis SQL配置文件中使用#{}取值为null时却不报错的解决方案。

    原因是因为#{kh_id} 这个参数名为小写,我之前写成了大写{#KH_ID}所以取不到值

  5. Openlayers 3 图层探查功能

    <body> <div id="map"></div> <script> var map=new ol.Map({ target:& ...

  6. OpenGL------显示列表

    我们已经知道,使用OpenGL其实只要调用一系列的OpenGL函数就可以了.然而,这种方式在一些时候可能导致问题.比如某个画面中,使用了数千个多边形来表现一个比较真实的人物,OpenGL为了产生这数千 ...

  7. more分页阅读

    相比cat命令,more可以更加灵活的去阅读查看文件. 1.命令格式 more [-dlfpcsu ] [-num ] [+/ pattern] [+ linenum] [file ... ] 2.命 ...

  8. 444A/CF

    题目链接[http://codeforces.com/problemset/problem/444/A] 题意:给出一个无向图,找出一个联通子图,定义密度#=v(顶点值的和)/e(边值的和). 条件: ...

  9. couldn't connect to server 127.0.0.1:27017 at src/mongo/shell/mongo.js:145

    当直接执行./mongo 出现这样的提示:couldn't connect to server 127.0.0.1:27017 at src/mongo/shell/mongo.js:145 解决: ...

  10. Monad / Functor / Applicative 浅析

    前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...