题意:http://acm.hdu.edu.cn/showproblem.php?pid=4117

思路:https://blog.csdn.net/u013306830/article/details/77586562

主要就是卡你内存,AC自动机的字典树得要用了再清空。

代码有点长吧。。。

  1. #include <cstdio>//sprintf islower isupper
  2. #include <iostream>//pair
  3. #include <string.h>//strstr substr strcat
  4. #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
  5. using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
  6. #define mem(a,b) memset(a,b,sizeof(a))
  7. #define pr printf
  8. #define sc scanf
  9. #define ls rt<<1
  10. #define rs rt<<1|1
  11. const int N=3e5+;
  12.  
  13. char s[N];
  14. int pos[],val[];
  15. //-------------------------------
  16. class mymap
  17. {
  18. public:
  19. int tot;
  20. int head[N];
  21. int SZ[N];
  22. int dfn[N],cnt;
  23. struct
  24. {
  25. int to,next;
  26. }edge[N];
  27. void Init(int n)
  28. {
  29. tot=;
  30. cnt=-;
  31. for(int i=;i<=n;++i)
  32. head[i]=SZ[i]=;
  33. }
  34. void add(int from,int to)
  35. {
  36. ++tot;
  37. edge[tot].to=to;
  38. edge[tot].next=head[from];
  39. head[from]=tot;
  40. }
  41. int dfs(int u)
  42. {
  43. ++cnt;
  44. dfn[u]=cnt;
  45. SZ[dfn[u]]=;
  46. for(int i=head[u];i;i=edge[i].next)
  47. {
  48. // cout<<edge[i].first<<endl;
  49. SZ[dfn[u]]+=dfs(edge[i].to);
  50. }
  51. return SZ[dfn[u]];
  52. }
  53. }TREE;
  54.  
  55. class seg_tree
  56. {
  57. public:
  58. int max_[N<<],add[N<<];
  59.  
  60. void up(int rt)
  61. {
  62. max_[rt]=max(max_[ls],max_[rs]);
  63. }
  64. void dn(int rt)
  65. {
  66. if(add[rt])
  67. {
  68. add[ls]=max(add[ls],add[rt]);
  69. add[rs]=max(add[rs],add[rt]);
  70. max_[ls]=max(max_[ls],add[rt]);
  71. max_[rs]=max(max_[rs],add[rt]);
  72. add[rt]=;
  73. }
  74. }
  75. void Build(int l,int r,int rt)
  76. {
  77. max_[rt]=;
  78. add[rt]=;
  79. if(l==r)
  80. {
  81. return;
  82. }
  83. int mid=(l+r)>>;
  84.  
  85. Build(l,mid,rt<<);
  86. Build(mid+,r,rt<<|);
  87. }
  88. int Q_dot(int pos,int l,int r,int rt)
  89. {
  90. if(l==r)
  91. {
  92. return max_[rt];
  93. }
  94.  
  95. int mid=(l+r)>>;
  96. dn(rt);
  97. if(pos<=mid)
  98. return Q_dot(pos,l,mid,rt<<);
  99. else
  100. return Q_dot(pos,mid+,r,rt<<|);
  101. }
  102. void update_qu(int L,int R,int V,int l,int r,int rt)
  103. {
  104. if(L>R)return;
  105. if(L<=l&&r<=R)
  106. {
  107. max_[rt]=max(max_[rt],V);
  108. add[rt]=max(add[rt],V);
  109. return;
  110. }
  111.  
  112. int mid=(l+r)>>;
  113. dn(rt);
  114. if(L<=mid)
  115. update_qu(L,R,V,l,mid,rt<<);
  116. if(R>mid)
  117. update_qu(L,R,V,mid+,r,rt<<|);
  118. up(rt);
  119. }
  120. }SEG;
  121.  
  122. class ac_automaton
  123. {
  124. public:
  125. int tot;
  126. int trie[N][];
  127. int fail[N];
  128. //other
  129. //--------------
  130. void Insert(int l,int r)
  131. {
  132. int rt=;
  133. for(int i=l;i<=r;++i)
  134. {
  135. int id=s[i]-'a'+;
  136. if(!trie[rt][id])
  137. {
  138. mem(trie[++tot],);
  139. trie[rt][id]=tot;
  140. }
  141. rt=trie[rt][id];
  142. }
  143. }
  144. queue<int>q;
  145. void Getfail()
  146. {
  147. for(int i=;i<=;++i)
  148. {
  149. int id=trie[][i];
  150. if(id)
  151. {
  152. fail[id]=;
  153. q.push(id);
  154. }
  155. }
  156. while(!q.empty())
  157. {
  158. int rt=q.front();q.pop();
  159. for(int i=;i<=;++i)
  160. {
  161. int id=trie[rt][i];
  162. if(id)
  163. {
  164. fail[id]=trie[fail[rt]][i];
  165. q.push(id);
  166. }
  167. else
  168. trie[rt][i]=trie[fail[rt]][i];
  169. }
  170. }
  171. }
  172. int Find(int l,int r,int id,int n)
  173. {
  174. int rt=;
  175. int pos=;
  176. int temp_max=;
  177. for(int i=l;i<=r;++i)
  178. {
  179. rt=trie[rt][s[i]-'a'+];
  180. pos=TREE.dfn[rt];
  181. int temp_val=SEG.Q_dot(pos,,n,)+val[id];
  182. temp_max=max(temp_max,temp_val);
  183. }
  184. SEG.update_qu(pos,pos+TREE.SZ[pos]-,temp_max,,n,);
  185. // for(int j=1;j<=n;++j)pr("%d ",SEG.Q_dot(j,1,n,1));
  186. // cout<<endl<<"----------------------------------"<<endl;
  187. return temp_max;
  188. }
  189. }AC;
  190.  
  191. void solve()
  192. {
  193. AC.tot=;
  194. mem(AC.trie[],);
  195. int n,tot;
  196. sc("%d",&n);
  197. pos[]=;
  198. for(int i=;i<=n;++i)
  199. {
  200. sc("%s %d",s+pos[i],&val[i]);
  201. int l=strlen(s+pos[i]);
  202. AC.Insert(pos[i],pos[i]+l-);
  203. pos[i+]=pos[i]+l;
  204. }
  205. tot=AC.tot;
  206. // pr("%s\n",s+1);
  207. AC.Getfail();
  208. TREE.Init(tot);
  209. SEG.Build(,tot,);
  210. for(int i=;i<=AC.tot;++i)
  211. TREE.add(AC.fail[i],i);
  212. TREE.SZ[]=TREE.dfs();
  213. int ans=;
  214. for(int i=;i<=n;++i)
  215. ans=max(ans,AC.Find(pos[i],pos[i+]-,i,tot));
  216. pr("%d\n",ans);
  217. }
  218.  
  219. int main()
  220. {
  221. int T,cnt=;
  222. sc("%d",&T);
  223. while(T--)
  224. {
  225. pr("Case #%d: ",++cnt);
  226. solve();
  227. }
  228. return ;
  229. }
  230.  
  231. /**************************************************************************************/

AC自动机fail树上dfs序建线段树+动态memset清空的更多相关文章

  1. CodeForces - 1207G :Indie Album(AC自动机 fail树上DFS)

    题意:有N个串,给出的形式是拼接给出,对于第i行:  (1,c)表示字符串i是单个字母c: (2,p,c)表示字符串i=在字符串p后面接上一个字母c. 然后给出M个提问,形式是(i,string).问 ...

  2. bzoj3306: 树(dfs序+倍增+线段树)

    比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...

  3. URAL 1890 . Money out of Thin Air (dfs序hash + 线段树)

    题目链接: URAL 1890 . Money out of Thin Air 题目描述: 给出一个公司里面上司和下级的附属关系,还有每一个人的工资,然后有两种询问: 1:employee x y z ...

  4. ac自动机fail树上按询问建立上跳指针——cf963D

    解法看着吓人,其实就是为了优化ac自动机上暴力跳fail指针.. 另外这题对于复杂度的分析很有学习价值 /* 给定一个母串s,再给定n个询问(k,m) 对于每个询问,求出长度最小的t,使t是s的子串, ...

  5. 7月13日考试 题解(DFS序+期望+线段树优化建图)

    T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...

  6. bzoj2819 DFS序 + LCA + 线段树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2819 题意:树上单点修改及区间异或和查询. 思维难度不高,但是题比较硬核. 整体思路是维护每一个结 ...

  7. hdu 3974 Assign the task(dfs序上线段树)

    Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...

  8. Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)

    877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...

  9. 用dfs序处理线段树的好题吗?

    https://www.cnblogs.com/mountaink/p/9878918.html 分析:每次的选取必须选最优的一条链,那我们考虑一下选择这条链后,把这条路上的点的权值更新掉,再采取选最 ...

随机推荐

  1. java 构造方法中super()和this()

    1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 2)this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句) 3)super: 它引用当前对 ...

  2. csp-s模拟90

    T1: 每格的不透明度相当与一个边权,转化为从起点到终点所有路径的最大值.实现最长路,最好用$dijk$. T2: 对于$N=100$,$M=8$,考虑状压$dp$.要用一种状态表示某一行的矩形覆盖情 ...

  3. Python 上下文管理器模块--contextlib

    在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...

  4. ubuntu18.04 systemctl

    systemd 是 Linux 下的一款系统和服务管理器,兼容 SysV 和 LSB 的启动脚本.systemd 的特性有:支持并行化任务:同一时候採用 socket 式与 D-Bus 总线式激活服务 ...

  5. arcgis python 列出一个表所有字段

    import arcpy inFeature = arcpy.GetParameterAsText(0) #原始数据 try: fieldList = arcpy.ListFields(inFeatu ...

  6. JS模拟Touch事件

    var ele = document.getElementsByClassName('target_node_class')[0] //may have x and y properties in s ...

  7. shell cat 用法

    cat命令的用途是连接文件或标准输入并打印. 1.命令格式:cat [选项] [文件]... 2.命令功能:cat主要有三大功能:1.一次显示整个文件:cat filename   --常用来显示文件 ...

  8. 安装RabbitMQ管理插件失败

    运行 rabbitmq-plugins.bat enable rabbitmq_management后提示失败信息  是因为erlang和RabbitMQ版本冲突导致

  9. SqlServer2008数据库的备份与还原

    1.先是备份数据 1.1.登录sql server management studio 1.2.选中需要备份数据库,右击鼠标,如下图: 1.3.点击备份之后,如下图; 2.数据还原准备 ps: 在开始 ...

  10. Server 2012使用Windows PowerShell cmdlet安装角色和角色服务功能

    Server 2012使用Windows PowerShell cmdlet安装角色和角色服务功能  Windows Server 2012 安装 SQL server 2008 出现了如下错误: 解 ...