[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)的抽象类 ...
随机推荐
- 基于ZooKeeper,Spring设计实现的参数系统
一.简介 基于ZooKeeper服务端.ZooKeeper Java客户端以及Spring框架设计的用于系统内部进行参数维护的系统. 二.设计背景 在我们日常开发的系统内部,开发过程中最常见的一项工作 ...
- Linux虚拟机配置静态ip地址
使用VMware搭建的虚拟机ip地址经常变动,在这里记录一下虚拟机设置静态ip地址: 首先通过VMware菜单栏编辑->虚拟网络编辑器->NAT设置查看子网ip地址和网关ip: 例如我这里 ...
- SphereEx 登陆 ApacheCon Asia|依托 ShardingSphere 可插拔架构体系打造数据应用完整生态
2021 年 8 月 8 日,ApacheCon 首次亚洲大会于线上正式闭幕.作为久负盛名的开源盛宴,本届 ApacheCon Asia 受到了海内外众多开源领域人士的关注. 作为 Apache 软件 ...
- Linux 下 SVN 的安装和配置
SVN 是一个自由开源的版本管理系统,它可以按照时间的顺序去管理文件.目录以及对其进行的修改.于今,它被广泛的用于互联网公司的项目版本管理中 工作原理 它的工作原理如下图所示 它是由一个SVN服务器和 ...
- C 库函数源码
github URL git://sourceware.org/git/glibc.git 码云 URL https://gitee.com/jason.R.xie/glibc.git
- Using C++ in VS Code
Using C++ in VS Code Get Started with C++ and Windows Subsystem for Linux in Visual Studio Code ...
- 【Java虚拟机11】线程上下文类加载器
前言 目前学习到的类加载的知识,都是基于[双亲委托机制]的.那么JDK难道就没有提供一种打破双亲委托机制的类加载机制吗? 答案是否定的. JDK为我们提供了一种打破双亲委托模型的机制:线程上下文类加载 ...
- Egg.js学习与实战系列 · 文件上传配置
在使用Egg.js搭建文件上传服务时,遇到了几个一般新手都会遇到的坑. 经查阅官方文档,Egg框架中默认使用egg-multipart插件进行文件上传,所以上传文件前需要做相关的配置. 上传文件提示: ...
- 助你上手Vue3全家桶之Vue-Router4教程
目录 1,前言 1,Router 2.1,跳转 2.2,打开新页面 3,Route 4,守卫 4.1,onBeforeRouteLeave 4.2,onBeforeRouteUpdate 4.3,路由 ...
- cm1 逆向分析
目录 cm1 逆向分析 前言 查壳分析 逆向分析 代码分析 qmemcpy分析 sub_401020函数分析 sub_401050函数分析 加密算法分析 POC代码编写 cm1 逆向分析 前言 还是先 ...