Description

给定一张包含N个单词的表,每个单词有个价值W。要求从中选出一个子序列使得其
中的每个单词是后一个单词的子串,最大化子序列中W的和。

Input

第一行一个整数TEST,表示数据组数。 
接下来TEST组数据,每组数据第一行为一个整数N。 
接下来N行,每行为一个字符串和一个整数W。

Output

TEST行,每行一个整数,表示W的和的最大值。 
 
 
数据规模 
设字符串的总长度为Len 
30.的数据满足,TEST≤5,N≤500,Len≤10^4 
100.的数据满足,TEST≤10,N≤20000,Len≤3*10^5

题解
首先对所有单词建AC自动机。另一个串是一个串的子串等价于这个串的任意前缀能够通过fail树到根的路径上走到另一个串。
我们用f[i]表示一定选i这个串的最大收益。
则f[i] = max(前缀能在fail树上走到的最大收益) + w[i]
用线段树维护fail树的dfs序,区间修改,单点查询
处理完每一个单词后直接在这个单词对应节点处加上f[i],相当于对于它的子树中所有点的答案取一个max
时间复杂度O(LlogL)
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 #define maxn 300020
  7
  8 typedef long long ll;
  9 struct node{
 10     int ls,rs;
 11     ll mx,tag;
 12 }sgt[maxn * 2];
 13 struct node2{
 14     int next,to;
 15 }e[maxn * 2];
 16 int head[maxn],cnt;
 17 char ch[maxn];
 18 int T,n;
 19 int nxt[maxn][26],tot,dfstime,fa[maxn];
 20 int fail[maxn],rt,cur,l[maxn],r[maxn],rec[maxn],w[maxn];
 21 int q[maxn],tt,hh;
 22 ll f[maxn],ans;
 23
 24 inline void clear(){
 25     for (int i = 1 ; i <= n ; i++) f[i] = 0;
 26     for (int i = 0 ; i <= tot ; i++) fail[i] = l[i] = r[i] = head[i] = fa[i] = rec[i] = 0;
 27     for (int i = 1 ; i <= tot ; i++) e[i].next = e[i].to = 0;
 28     for (int i = 0 ; i <= tot ; i++) memset(nxt[i],0,sizeof(nxt[i]));
 29     for (int i = 1 ; i <= cnt ; i++) sgt[i].tag = sgt[i].mx = 0 , sgt[i].ls = sgt[i].rs = 0;
 30     tot = cnt = dfstime = 0;
 31     ans = 0;
 32 }
 33 inline void adde(int x,int y){
 34     e[++cnt].to = y;
 35     e[cnt].next = head[x];
 36     head[x] = cnt;
 37 }
 38 inline void insert(int x){
 39     if ( !nxt[cur][x] ) nxt[cur][x] = ++tot , fa[tot] = cur;
 40     cur = nxt[cur][x];
 41 }
 42 void dfs(int x){
 43     if ( x ) l[x] = ++dfstime;
 44     for (int i = head[x] ; i ; i = e[i].next) dfs(e[i].to);
 45     r[x] = dfstime;
 46 }
 47 void build(int &x,int l,int r){
 48     x = ++cnt;
 49     if ( l == r ) return;
 50     int mid = (l + r) >> 1;
 51     build(sgt[x].ls,l,mid);
 52     build(sgt[x].rs,mid + 1,r);
 53 }
 54 void build_AC(){
 55     tt = hh = 0;
 56     for (int i = 0 ; i < 26 ; i++) if ( nxt[0][i] ) q[tt++] = nxt[0][i];
 57     while ( hh < tt ){
 58         int x = q[hh++];
 59         for (int i = 0 ; i < 26 ; i++){
 60             if ( nxt[x][i] ){
 61                 int p = fail[x];
 62                 while ( !nxt[p][i] && p ) p = fail[p];
 63                 fail[nxt[x][i]] = nxt[p][i]; //不是p
 64                 q[tt++] = nxt[x][i];
 65             }
 66         }
 67     }
 68     for (int i = 1 ; i <= tot ; i++) adde(fail[i],i);
 69     dfs(0);
 70     cnt = 0;
 71     build(rt,1,tot);
 72 }
 73 inline void update(int x){
 74     sgt[x].mx = max(sgt[sgt[x].ls].mx,sgt[sgt[x].rs].mx);
 75 }
 76 inline void add(int x,ll d){
 77     sgt[x].tag = max(sgt[x].tag,d);
 78     sgt[x].mx = max(sgt[x].mx,d);
 79 }
 80 inline void pushdown(int x){
 81     if ( sgt[x].tag != 0 ){
 82         add(sgt[x].ls,sgt[x].tag);
 83         add(sgt[x].rs,sgt[x].tag);
 84         sgt[x].tag = 0;
 85     }
 86 }
 87 void modify(int x,int l,int r,int ls,int rs,ll d){
 88     if ( ls <= l && rs >= r ){
 89         add(x,d);
 90         return;
 91     }
 92     pushdown(x);
 93     int mid = (l + r) >> 1;
 94     if ( ls <= mid ) modify(sgt[x].ls,l,mid,ls,rs,d);
 95     if ( rs > mid ) modify(sgt[x].rs,mid + 1,r,ls,rs,d);
 96     update(x);
 97 }
 98 ll query(int x,int l,int r,int id){
 99     if ( l == r ) return sgt[x].mx;
100     pushdown(x);
101     int mid = (l + r) >> 1;
102     if ( id <= mid ) return query(sgt[x].ls,l,mid,id);
103     return query(sgt[x].rs,mid + 1,r,id);
104 }
105 void Dodp(){
106     for (int i = 1 ; i <= n ; i++){
107         int p = rec[i];
108         while ( p ){
109             f[i] = max(f[i],query(rt,1,tot,l[p]));
110             p = fa[p];
111         }
112         f[i] += w[i];
113         f[i] = max(0ll,f[i]);
114         modify(rt,1,tot,l[rec[i]],r[rec[i]],f[i]);
115     }
116     for (int i = 1 ; i <= n ; i++) ans = max(ans,f[i]);
117 }
118 int main(){
119     freopen("input.txt","r",stdin);
120     scanf("%d",&T);
121     while ( T-- ){
122         clear();
123         scanf("%d",&n);
124         for (int i = 1 ; i <= n ; i++){
125             scanf("%s",ch) , scanf("%d",&w[i]);
126             int l = strlen(ch);
127             cur = 0;
128             for (int j = 0 ; j < l ; j++){
129                 insert(ch[j] - 'a');
130             }
131             rec[i] = cur;
132         }
133         build_AC();
134         Dodp();
135         printf("%lld\n",ans);
136     }
137     return 0;
138 }

转载于:https://www.cnblogs.com/zqq123/p/5505824.html

bzoj 2905 背单词相关推荐

  1. 【青少年编程】黄羽恒:我要背单词

    「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复[Scratch]或[Python],即可进入.如果加入了之前的社群不需要重复加入. 微信后台回复"资料下载&quo ...

  2. 不用“背”单词,一个方法从普通二本到哥伦比亚大学:我是如何做到的?

    "学英语太难.太费劲了."我听过无数人这么说. 然而,我的学员们,却都只用了短短3-6个月时间,就以惊人速度提高了英语: 小磊:勉强踩着2本线上了大学,四级考了3次没过,毕业时却拿 ...

  3. 别光顾着背单词了,每天花18分钟做这件事,英语水平暴增!

    在知乎上看过一个问题:在当今社会,英语还重要吗? 点赞第一的回答是-- 英语可以差,但你的口语一定要好! 你记住了1万个单词.将语法书倒背如流.英语成绩名列前茅.英语证书一大摞. 但你的口语差,看见老 ...

  4. 少壮不努力,老大背单词

    少壮不努力,老大背单词 你必须非常努力,才可以看起来毫不费力 uncouth (adj.) 粗鲁的,不文明的 I am embarrassed by your uncouth manners epit ...

  5. 微信背单词类小程序,小鸡单词源码下载,打卡微信小程序

    微信背单词类小程序,小鸡单词源码下载,微信小程序开发学习案例,小程序开发教程.一个用来背单词每天打卡的微信小程序,还有词汇测试,包含多种词库后台由腾讯云wafer解决方案. 前段时间开始学做微信小程序 ...

  6. python写背单词软件_python背单词小程序

    import random as t #创建单词序列 words=("easy","difficult","answer","co ...

  7. 必背单词_研究生满大街走?真实数据来啦 真题必背单词Day10

    研究生满大街走?真实数据来啦 我国现在有多少研究生了?先上图: 从以上数据可以得知,1995年至2019年,我国的研究生入学人数共计约878万人. 这个数字看似很大,但不要忽视了我国的总人口.简单计算 ...

  8. 一款让你“乐词不疲”的背单词神器

    PMCAFF(www.pmcaff.com):最大互联网产品社区,是百度,腾讯,阿里等产品经理的学习交流平台.定期出品深度产品观察,互联产品研究首选. ▍产品概述 1.1 体验环境 产品名称:乐词 版 ...

  9. python 对excel文件进行分词并进行词频统计_教你背单词 | 利用python分析考研英语阅读并生成词频降序表...

    作为一名19考研er 距离我考研结束已经过去大半年 想和大家分享一下当初背单词的骚操作 众所周知 考研英语"得阅读者得天下" 提升词汇量又是提高阅读的关键 那么问题来了? 大家都是 ...

最新文章

  1. 01背包【动态规划】
  2. python网络爬虫的基本步骤-详解Python网络爬虫功能的基本写法
  3. 第十七篇 计算机组成原理
  4. dynamic flash xml news----滚动新闻
  5. android格式化时间中文版,Android 仿微信聊天时间格式化显示功能
  6. Android系统的开机画面显示过程分析
  7. spinlock剖析与改进
  8. window统计文本字节_【NLP】机器如何认识文本 ?NLP中的Tokenization方法总结
  9. fastdfs暗转 linux_Linux下安装fastDFS
  10. sublime注释乱码c语言,ConvertToUTF8:解决 Sublime Text的乱码问题
  11. j2ee和mysql怎么连接_Eclipse下配置j2ee开发环境及与MySQL数据库的连接
  12. ArcGIS API for JavaScript 打印
  13. android登录ins,在android中集成instagram身份验证
  14. php laravel mix,Laravel框架 之 Mix
  15. gtk下的messagebox
  16. 【Python 爬虫系列非专业教学】(3)手把手教你获取猫眼电影 Top 100 榜单
  17. 由 Apache Kylin 组建的 Kyligence 公司获得数百万美元的天使轮投资
  18. 第一节 Python环境搭建
  19. Python: queue.Queue
  20. 卷积神经网络架构不包含,卷积神经网络架构分析

热门文章

  1. 解决:Module not found: node_modules\sass-loader\package.json (directory description file)
  2. P2896 [USACO08FEB]一起吃饭Eating Together 解题报告
  3. markdown 常用语法总结 - 个人版
  4. l2-006 树的遍历
  5. Cookie 的规范介绍
  6. 服务器磁盘操作系统双机软件集成,实战:ROSE HA双机热备系统安装指南
  7. 东北考生到南方学计算机,为啥东北考生都想去南方,而南方学生很少考东北,看看他们怎么说...
  8. c语言中listempty函数,list_empty()和list_empty_careful()
  9. 口述完SpringMVC执行流程,面试官就让同事回家等消息了
  10. docker安装postgres