BZOJ2905 : 背单词
首先对所有单词建立AC自动机,$S$是$T$的子串等价于$T$的某个前缀通过$fail$链可以走到$S$的终止节点,即$S$的终止节点是$T$某个前缀在$fail$树上的祖先。
设$f[i]$表示考虑了前$i$个单词,且第$i$个单词必选时子序列价值的最大值,
则$f[i]=\max(单词i每个前缀的贡献)+w[i]$,计算出$f[i]$后再在单词$i$终止节点在$fail$树的子树里打上$f[i]$的标记,线段树维护即可。
时间复杂度$O(L\log L)$。
- #include<cstdio>
- #include<cstring>
- const int N=20010,M=300010;
- typedef long long ll;
- char s[M];
- int tot,son[M][26],fail[M],q[M],G[M],NXT[M],st[M],en[M],dfn;
- int Case,n,i,j,w[N],g[N],v[M],nxt[M],ed;
- ll tag[1050000],dp,ans;
- inline void ins(int p){
- for(int l=strlen(s),x=0,i=0,w;i<l;i++){
- if(!son[x][w=s[i]-'a'])son[x][w]=++tot;
- v[++ed]=x=son[x][w];nxt[ed]=g[p];g[p]=ed;
- }
- }
- void make(){
- int h=1,t=0,i,j,x;fail[0]=-1;
- for(i=0;i<26;i++)if(son[0][i])q[++t]=son[0][i];
- while(h<=t)for(x=q[h++],i=0;i<26;i++)
- if(son[x][i])fail[son[x][i]]=son[fail[x]][i],q[++t]=son[x][i];
- else son[x][i]=son[fail[x]][i];
- }
- void dfs(int x){
- st[x]=++dfn;
- for(int i=G[x];i;i=NXT[i])dfs(i);
- en[x]=dfn;
- }
- void build(int x,int a,int b){
- tag[x]=0;
- if(a==b)return;
- int mid=(a+b)>>1;
- build(x<<1,a,mid),build(x<<1|1,mid+1,b);
- }
- inline void up(ll&a,ll b){if(a<b)a=b;}
- void change(int x,int a,int b,int c,int d){
- if(c<=a&&b<=d){up(tag[x],dp);return;}
- int mid=(a+b)>>1;
- if(c<=mid)change(x<<1,a,mid,c,d);
- if(d>mid)change(x<<1|1,mid+1,b,c,d);
- }
- void ask(int x,int a,int b,int c){
- up(dp,tag[x]);
- if(a==b)return;
- int mid=(a+b)>>1;
- if(c<=mid)ask(x<<1,a,mid,c);else ask(x<<1|1,mid+1,b,c);
- }
- int main(){
- scanf("%d",&Case);
- while(Case--){
- scanf("%d",&n);
- for(i=1;i<=n;i++)scanf("%s%d",s,&w[i]),ins(i);
- make();
- for(i=1;i<=tot;i++)NXT[i]=G[fail[i]],G[fail[i]]=i;
- dfs(0);
- build(1,1,dfn);
- for(ans=0,i=1;i<=n;i++){
- for(dp=0,j=g[i];j;j=nxt[j])ask(1,1,dfn,st[v[j]]);
- up(ans,dp+=w[i]);
- change(1,1,dfn,st[v[g[i]]],en[v[g[i]]]);
- }
- printf("%lld\n",ans);
- for(i=dfn=0;i<=tot;i++)for(fail[i]=G[i]=j=0;j<26;j++)son[i][j]=0;
- for(ed=tot=0,i=1;i<=n;i++)g[i]=0;
- }
- return 0;
- }
BZOJ2905 : 背单词的更多相关文章
- BZOJ2905: 背单词 AC自动机+fail树+线段树
$zjq$神犇一眼看出$AC$自动机 $Orz$ 直接就讲做法了 首先对每个串建出$AC$自动机 将$fail$树找到 然后求出$dfs$序 我们发现一个单词 $S_i$是$S_j$的子串当且仅当$S ...
- 【BZOJ2905】背单词 fail树+DFS序+线段树
[BZOJ2905]背单词 Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行 ...
- 做中学(Learning by Doing)之背单词-扇贝网推荐
做中学(Learning by Doing)之背单词-扇贝网推荐 看完杨贵福老师(博客,知乎专栏,豆瓣)的「继续背单词,8个月过去了」,我就有写这篇文章的冲动了,杨老师说: 有时候我会感觉非常后悔,如 ...
- “我爱背单词”beta版发布与使用说明
我爱背单词BETA版本发布 第二轮迭代终于画上圆满句号,我们的“我爱背单词”beta版本已经发布. Beta版本说明 项目名称 我爱背单词 版本 Beta版 团队名称 北京航空航天大学计算机学院 拒 ...
- BZOJ4567[Scoi2016]背单词
4567: [Scoi2016]背单词 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 304 Solved: 114 [Submit][Status] ...
- 《我爱背单词》 Alpha版 发布说明
——发布地址(baidu网盘) http://pan.baidu.com/s/15omtB ——简介 <我爱背单词>是一款英语单词记忆和管理辅助软件,旨在帮助广大考生在短期内攻克GRE. ...
- [No000057]一个人默默背单词,小心被传染哦
不日凛冬将至,全国各地,已有多名少侠因季节变化,出现了不同程度的四肢不勤.bd不分的症状.具体表现为—— 包大人在此高能预警:不想背单词,有可能你已经被传染了. 好好的,怎么突然不想背单词了 哈佛医学 ...
- [No000014]听说不背单词,考英语会是这种下场-我们为什么必须背单词?
由于英语对于一个程序员来说,重要性你懂得.因此我会开始逐渐在博客上加入英语的一些东西. 听说不背单词,考英语会是这种下场 在中国, 「学英语」大抵遵循着这样一条 罗蒙诺索夫质量守恒定律 因为英语学着学 ...
- Supermemo背单词7周年纪念
从2007年2月1日开始,用Supermemo背单词7周年了,在2013年11月21日将单词表Reset,重新开始Review以前背过的单词,并慢慢加入听写VOA时遇到的生词.
随机推荐
- [Effective JavaScript 笔记]第39条:不要重用父类的属性名
假设想给上节讲的场景图库添加收集诊断信息的功能.这对于调试和性能分析很有用. 38条示例续 给每个Actor实例一个唯一的标识数. 添加标识数 function Actor(scene,x,y){ t ...
- iphone数据存储之-- Core Data的使用(一)
http://www.cnblogs.com/xiaodao/archive/2012/10/08/2715477.html 一.概念 1.Core Data 是数据持久化存储的最佳方式 2.数据最终 ...
- select function in ruby
http://ruby-doc.org/ http://ruby-doc.org/core-2.3.0/Array.html#method-i-select [1,2,3,4,5].select { ...
- C#开发实例 键盘篇
键盘的操作控制: 键盘和鼠标一样是重要输入设备的一部分.开发过程中,会涉及到很多的键盘操作控制. 2.1获取键盘信息 ①获取组合键 Windows中有很多默认的组合键,如Ctrl+v,Ctrl+A.本 ...
- LNK2005 连接错误解决办法
nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@ ...
- HDOJ 1878 欧拉回路 nyoj 42一笔画问题
#include<cstdio> #include<cstring> ]; int find(int x) { if(visited[x]!=x) return find(vi ...
- C语言指针总结
C语言中的精华是什么,答曰指针,这也是C语言中唯一的难点. C是对底层操作非常方便的语言,而底层操作中用到最多的就是指针,以后从事嵌入式开发的朋友们,指针将陪伴我们终身. 本文将从八个常见的方面来透视 ...
- 转MYSQL学习(二) 运算符
MYSQL中的运算符很多,这一节主要讲MYSQL中有的,而SQLSERVER没有的运算符 安全等于运算符(<=>) 这个操作符和=操作符执行相同的比较操作,不过<=>可以用来判 ...
- JavaScript封装成类
JavaScript在WEB编程中能起到很大的作用,将一些常用的功能写成JavaScript类库. 将下面代码保存为Common.js 类库功能: 1.Trim(str)--去除字符串两边的空格 2. ...
- 理解C#中的闭包
闭包的概念 内层的函数可以引用包含在它外层的函数的变量,即使外层函数的执行已经终止.但该变量提供的值并非变量创建时的值,而是在父函数范围内的最终值. 闭包的优点 使用闭包,我们可以轻松的访问外层函数定 ...