2746

思路:

  建立ac自动机,然后把fail树抽出来;

  然后在fail树上走lca(神奇);

代码:

  1. #include <cstdio>
  2. #include <vector>
  3. #include <cstring>
  4. #include <iostream>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. #define maxn 1000005
  10. #define mod 1000000007LL
  11.  
  12. struct TreeNodeType {
  13. int id;
  14.  
  15. long long dis;
  16.  
  17. TreeNodeType *next[],*fail;
  18.  
  19. TreeNodeType()
  20. {
  21. id=,dis=,fail=NULL;
  22. for(int i=;i<;i++) next[i]=NULL;
  23. }
  24. };
  25. struct TreeNodeType *map[maxn<<],*que[maxn<<],*root;
  26.  
  27. int n,m,deep[maxn<<],f[maxn<<],top[maxn<<],head[maxn<<];
  28. int E[maxn<<],V[maxn<<],tot,cnt,len,size[maxn<<];
  29.  
  30. char ch[maxn<<];
  31.  
  32. vector<int>vec[maxn<<];
  33.  
  34. inline void in(int &now)
  35. {
  36. char Cget=getchar();now=;
  37. while(Cget>''||Cget<'') Cget=getchar();
  38. while(Cget>=''&&Cget<='')
  39. {
  40. now=now*+Cget-'';
  41. Cget=getchar();
  42. }
  43. }
  44.  
  45. void dfs1(int now,int fa)
  46. {
  47. f[now]=fa,deep[now]=deep[fa]+,size[now]=;
  48. for(int i=head[now];i;i=E[i])
  49. {
  50. if(V[i]==fa) continue;
  51. dfs1(V[i],now),size[now]+=size[V[i]];
  52. }
  53. }
  54.  
  55. void dfs2(int now,int chain)
  56. {
  57. top[now]=chain;int pos=;
  58. for(int i=head[now];i;i=E[i])
  59. {
  60. if(V[i]==f[now]) continue;
  61. if(size[V[i]]>size[pos]) pos=V[i];
  62. }
  63. if(pos) dfs2(pos,chain);else return ;
  64. for(int i=head[now];i;i=E[i])
  65. {
  66. if(V[i]==pos||V[i]==f[now]) continue;
  67. dfs2(V[i],V[i]);
  68. }
  69. }
  70.  
  71. inline int lca(int x,int y)
  72. {
  73. for(;top[x]!=top[y];)
  74. {
  75. if(deep[top[x]]<deep[top[y]]) swap(x,y);
  76. x=f[top[x]];
  77. }
  78. if(deep[x]>deep[y]) swap(x,y);
  79. return x;
  80. }
  81.  
  82. int main()
  83. {
  84. in(n);root=new TreeNodeType;
  85. root->id=++tot,map[root->id]=root;
  86. for(int i=;i<=n;i++)
  87. {
  88. scanf("%s",ch),len=strlen(ch);
  89. TreeNodeType *now=root;int pos;
  90. for(int j=;j<len;j++)
  91. {
  92. pos=ch[j]-'a';
  93. if(now->next[pos]==NULL)
  94. {
  95. now->next[pos]=new TreeNodeType,now->next[pos]->id=++tot;
  96. map[tot]=now->next[pos],now->next[pos]->dis=(now->dis*26LL+pos)%mod;
  97. }
  98. vec[i].push_back(now->next[pos]->id),now=now->next[pos];
  99. }
  100. }
  101. int h=,tail=,u,v;que[]=root;
  102. while(h<tail)
  103. {
  104. TreeNodeType *now=que[h++],*temp=NULL;
  105. for(int i=;i<;i++)
  106. {
  107. if(now->next[i]==NULL) continue;
  108. if(now==root) now->next[i]->fail=root;
  109. else
  110. {
  111. temp=now->fail;
  112. while(temp!=NULL)
  113. {
  114. if(temp->next[i]!=NULL)
  115. {
  116. now->next[i]->fail=temp->next[i];
  117. break;
  118. }
  119. temp=temp->fail;
  120. }
  121. if(temp==NULL) now->next[i]->fail=root;
  122. }
  123. que[tail++]=now->next[i];
  124. u=now->next[i]->id,v=now->next[i]->fail->id;
  125. E[++cnt]=head[u],V[cnt]=v,head[u]=cnt;
  126. E[++cnt]=head[v],V[cnt]=u,head[v]=cnt;
  127. }
  128. }
  129. dfs1(,),dfs2(,);
  130. in(m);int a,a1,b,b1;
  131. for(;m--;)
  132. {
  133. in(a),in(a1),in(b),in(b1);
  134. printf("%lld\n",map[lca(vec[a][a1-],vec[b][b1-])]->dis);
  135. }
  136. return ;
  137. }

AC日记——[HEOI2012]旅行问题 bzoj 2746的更多相关文章

  1. AC日记——[HNOI2008]GT考试 bzoj 1009

    1009 思路: KMP上走DP(矩阵加速): DP[i][j]表示当前在第i位,同是匹配到不吉利串的第j位的方案数: 代码: #include <bits/stdc++.h> using ...

  2. AC日记——明明的烦恼 bzoj 1005

    1005 思路: prufer编码+组合数: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 #de ...

  3. AC日记——Mato的文件管理 bzoj 3289

    3289 思路: 莫队求区间逆序对个数,树状数组维护: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 500 ...

  4. AC日记——[Scoi2010]序列操作 bzoj 1858

    1858 思路: 恶心: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 struct Tree ...

  5. AC日记——[ZJOI2007]报表统计 bzoj 1058

    1058 思路: 平衡树的题: 然而我的平衡树写一次炸一次QwQ: 而且各种tle: 所以stl水过: 代码: #include <set> #include <cstdio> ...

  6. AC日记——[JSOI2007]建筑抢修 bzoj 1029

    1029 思路: 贪心,而且,stl水过: 然而神特么输出que.size()就错! 代码: #include <queue> #include <cstdio> #inclu ...

  7. AC日记——[JSOI2008]火星人prefix bzoj 1014

    1014 思路: 平衡树+二分答案+hash: 好了懂了吧. 代码: #include <cstdio> #include <cstring> #include <ios ...

  8. AC日记——[HAOI2007]覆盖问题 bzoj 1052

    1052 思路: 二分答案: 二分可能的长度: 然后递归判断长度是否可行: 先求出刚好覆盖所有点的矩形: 可行的第一个正方形在矩形的一个角上: 枚举四个角上的正方形,然后删去点: 删去一个正方形后,递 ...

  9. AC日记——[SCOI2008] 着色方案 bzoj 1079

    1079 思路: dp: 我们如果dp方程为15维,每维记录颜色还有多少种: 不仅tle,mle,它还re: 所以,我们压缩一下dp方程: 方程有6维,第i维记录有多少种颜色还剩下i次: 最后还要记录 ...

随机推荐

  1. C# 获取方法所在的 命名空间 类名 方法名

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  2. 【bzoj3514】Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树

    题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 输入 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M行,代表图中的每条边 ...

  3. android中常见的命名及其特点详解

    Paseal命名法 Paseal命名法特点:String MyName-DelphiInt MyAge每个单词首字母大写 Camel命名法 Camel(驼峰的意思)命名法特点:String myNam ...

  4. 'com.alibaba.fastjson.support.spring.FastJsonpResponseBodyAdvice' is。。。。

    com.alibaba.fastjson版本1.2.43版本在通过xml方式配置spring的时候会出现这个个奇怪的问题: Class 'com.alibaba.fastjson.support.sp ...

  5. 【BZOJ 3232】圈地游戏 二分+SPFA判环/最小割经典模型

    最小割经典模型指的是“一堆元素进行选取,对于某个元素的取舍有代价或价值,对于某些对元素,选取后会有额外代价或价值”的经典最小割模型,建立倒三角进行最小割.这个二分是显然的,一开始我也是想到了最小割的那 ...

  6. linux+GraphicsMagick 安装

    转摘自:http://blog.csdn.net/fhqsse220/article/details/12995763 GraphicsMagick 安装 下载软件:download:ftp://ft ...

  7. JavaScript学习笔记——浅拷贝、深拷贝

    参考自:http://www.cnblogs.com/yichengbo/archive/2014/07/10/3835882.html 一.数组的深浅拷贝 在使用JavaScript对数组进行操作的 ...

  8. 【Foreign】最大割 [线性基]

    最大割 Time Limit: 15 Sec  Memory Limit: 256 MB Description Input Output Sample Input 3 6 1 2 1 1 2 1 3 ...

  9. HDU5772 String problem

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission ...

  10. 【洛谷 P1337】[JSOI2004]平衡点 / 吊打XXX (模拟退火)

    题目链接 正解就算了吧,谁叫我理生化 语数外 政史地都菜呢 模拟退火真玄学,不知道发生了什么就跑出答案了,原理就算了吧,能用(pianfen)就好. 当重物平衡时,势能一定是最小的,于是当我随机出一个 ...