[loj3049]字符串问题
考虑将所有A串向所能支配的B串连边,B串向满足B串是A串前缀的A串连边,在A串上有点权,跑最长路即可
但这样前缀的边太多,考虑优化:在后缀树上,将这些串插入进去(注意相同的串A串要在B串下面),并将父亲向儿子连边,那么相当于实现了上面的问题
但这样还有一个问题:需要将所有A串裂为两个点,因为并不是经过A串就一定可以有收益,而是要选择A串(即走A串连向B串的边)才有收益

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 1000005
4 #define oo 1e18
5 struct ji{
6 int nex,to;
7 }edge[N];
8 vector<pair<int,int> >v[N];
9 int V,E,las,t,n,m,q,l,r,la[N],len[N],nex[N],ch[N][31],f[N][21],head[N],vis[N],val[N];
10 long long ans,dp[N];
11 char s[N];
12 void add(int c){
13 int p=las,np=las=++V;
14 len[V]=len[p]+1;
15 while ((p)&&(!ch[p][c])){
16 ch[p][c]=las;
17 p=nex[p];
18 }
19 if (!p)nex[las]=1;
20 else{
21 int q=ch[p][c],nq=++V;
22 memcpy(ch[nq],ch[q],sizeof(ch[q]));
23 nex[nq]=nex[q];
24 len[nq]=len[p]+1;
25 ch[p][c]=nex[q]=nex[las]=nq;
26 while ((p)&&(ch[p][c]==q)){
27 ch[p][c]=nq;
28 p=nex[p];
29 }
30 }
31 }
32 int query(int k,int l){
33 for(int i=20;i>=0;i--)
34 if (len[f[k][i]]>=l)k=f[k][i];
35 return k;
36 }
37 void add(int x,int y){
38 edge[E].nex=head[x];
39 edge[E].to=y;
40 head[x]=E++;
41 }
42 long long dfs(int k){
43 if (vis[k])return oo;
44 if (dp[k]>=0)return dp[k];
45 vis[k]=1;
46 long long ans=0;
47 for(int i=head[k];i!=-1;i=edge[i].nex)ans=max(ans,dfs(edge[i].to));
48 dp[k]=ans+val[k];
49 vis[k]=0;
50 return dp[k];
51 }
52 int main(){
53 scanf("%d",&t);
54 while (t--){
55 scanf("%s",s);
56 int l=strlen(s);
57 las=V=1;
58 E=ans=0;
59 memset(head,-1,sizeof(head));
60 memset(vis,0,sizeof(vis));
61 memset(ch,0,sizeof(ch));
62 memset(val,0,sizeof(val));
63 memset(dp,-1,sizeof(dp));
64 for(int i=l-1;i>=0;i--){
65 add(s[i]-'a');
66 la[i]=las;
67 }
68 for(int i=1;i<=V;i++)f[i][0]=nex[i];
69 for(int i=1;i<=20;i++)
70 for(int j=1;j<=V;j++)f[j][i]=f[f[j][i-1]][i-1];
71 for(int i=1;i<=V;i++){
72 v[i].clear();
73 v[i].push_back(make_pair(len[nex[i]],-nex[i]));
74 v[i].push_back(make_pair(len[i],-i));
75 }
76 int VV=V;
77 scanf("%d",&n);
78 for(int i=1;i<=n;i++){
79 scanf("%d%d",&l,&r);
80 int k=query(la[l-1],r-l+1);
81 val[++V]=r-l+1;
82 v[k].push_back(make_pair(r-l+1,-V));
83 }
84 scanf("%d",&m);
85 for(int i=1;i<=m;i++){
86 scanf("%d%d",&l,&r);
87 int k=query(la[l-1],r-l+1);
88 v[k].push_back(make_pair(r-l+1,-(++V)));
89 }
90 for(int i=1;i<=V-n-m;i++){
91 sort(v[i].begin(),v[i].end());
92 for(int j=0;j<v[i].size();j++){
93 if (val[-v[i][j].second]){
94 add(++V,-v[i][j].second);
95 v[i][j].second=-V;
96 }
97 if (j)add(-v[i][j-1].second,-v[i][j].second);
98 }
99 }
100 scanf("%d",&q);
101 for(int i=1;i<=q;i++){
102 scanf("%d%d",&l,&r);
103 add(VV+l,VV+n+r);
104 }
105 for(int i=VV+n+m+1;i<=V;i++)ans=max(ans,dfs(i));
106 if (ans>=oo)ans=-1;
107 printf("%lld\n",ans);
108 }
109 }
[loj3049]字符串问题的更多相关文章
- [LOJ3049] [十二省联考 2019] 字符串问题
题目链接 LOJ:https://loj.ac/problem/3049 洛谷:https://www.luogu.org/problemnew/show/P5284 BZOJ:https://www ...
- 并不对劲的loj3049:p5284:[十二省联考]字符串问题
题目大意 给出字符串\(S(|S|\leq2\times10^5)\), \(na(na\leq2\times 10^5)\)个区间\([l_i,r_i]\)表示\(S_{l_i},S_{l_i+1} ...
- LOJ3049 [十二省联考2019] 字符串问题 【后缀自动机】【倍增】【拓扑排序】
题目分析: 建出后缀自动机,然后把A串用倍增定位到后缀自动机上,再把B串用倍增定位到后缀自动机上. SAM上每个点上的A串根据长度从小到大排序,建点,依次连边. 再对于SAM上面每个点,连到儿子的边, ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- JavaScript 字符串实用常操纪要
JavaScript 字符串用于存储和处理文本.因此在编写 JS 代码之时她总如影随形,在你处理用户的输入数据的时候,在读取或设置 DOM 对象的属性时,在操作 Cookie 时,在转换各种不同 Da ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Redis的简单动态字符串实现
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,sds)的抽象类 ...
随机推荐
- Mysql读写分离集群的搭建且与MyCat进行整合
1. 概述 老话说的好:不熟悉的东西不要不懂装懂,做人要坦诚,知道就是知道,不知道就是不知道. 言归正传,今天我们来聊聊 Mysql主从读写分离集群是如何搭建的,并且聊一下如何用 MyCat 去访问这 ...
- 工作3年的Java程序员,轻松拿到阿里P6Offer,只因为他搞明白了Redis这几个问题!!
Redis中的多路复用模型 Redis6用到了多线程?那多线程应用在哪些地方,引入多线程后,又改如何保证线程安全性呢? 同时,如何在性能和线程安全性方面做好平衡? 关于Redis的单线程模型 在Red ...
- Upload-labs通关指南(上) 1-10
Upload-labs 所有文章和随笔(随笔将不于csdn更新)将于我的个人博客(移动端暂未适配)第一时间更新. 一些网站存在文件上传接口,一旦存在这个接口就有可能存在漏洞. 文件上传漏洞的逻辑是将一 ...
- LDAP-初见
目录 什么是LDAP? LDAP 协议能解决什么问题? Spring Boot中使用LDAP来统一管理用户信息 添加用户 连接LDAP服务端 什么是LDAP? LDAP 的全称是 Lightweigh ...
- 【数据结构与算法Python版学习笔记】图——拓扑排序 Topological Sort
概念 很多问题都可转化为图, 利用图算法解决 例如早餐吃薄煎饼的过程 制作松饼的难点在于知道先做哪一步.从图7-18可知,可以首先加热平底锅或者混合原材料.我们借助拓扑排序这种图算法来确定制作松饼的步 ...
- python标准库glob 递归目录下所有文件
import glob for i in glob.glob(r'C:\Desktop\**',recursive=True): print(i) """ re:?*[0 ...
- 第七次Scrum Metting
日期:2021年5月5日 会议主要内容概述:前后端对接,以及接下来的测试优化等工作. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇龙 后端 测试数据模块和 ...
- elasticsearch嵌套对象的映射
在es中,我们有时候可能需要映射,{ "field" : "xx" , "field01" : [] }这样格式的嵌套对象,默认情况下es会 ...
- DDD领域驱动设计-设计规范-Ⅵ
不以规矩,不能成方圆. -战国·邹·孟轲<孟子·离娄章句上 ...
- 重学STM32---(十)之CAN通信(二)
目录 前言 程序编写 主代码 测试 前言 CAN协议是非常难的,但是在stm32中却是简单的,只需要我们配置寄存器即可,,,即使这样,我在学习的时候也遇到了许多困难 程序编写 1.开时钟,不用说 ...