[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)的抽象类 ...
随机推荐
- PAT (Basic Level) Practice (中文)1007 素数对猜想 (20分)
1007 素数对猜想 (20分) 让我们定义dn为:dn = pn+1 − pn,其中pi是第i个素数.显然有d1 = 1,且对于n > 1有dn是偶数."素数对猜想"认 ...
- Install WSL
Install WSL Prerequisites You must be running Windows 10 version 2004 and higher (Build 19041 and hi ...
- 使用寄存器点亮LED
1. 项目:使用stm32寄存器点亮LED, 分别点亮红.绿.蓝3个灯. 2. 代码: 只需要编写main.c程序,stm3210x.h程序为空(只需要新建即可). 2.1 点亮绿灯main.c程序 ...
- 2021 从零开始学Git【新版本Git - 8000字详细介绍】
我写的这篇文章,主要是记录自己的学习过程,也希望帮助读者少踩坑(比如不同版本可能命令不兼容等).本文面向git零基础初学者,建议读者按照文中命令自己全部操作一遍(注意运行环境). 我的运行环境:win ...
- 【二食堂】Beta - 设计和计划
Beta设计和计划 需求再分析 根据助教.老师.用户以及各个团队PM的反馈意见,我们的项目目前有以下问题: 功能不完整 实用价值不高 两方面的缺陷,所以在Beta阶段,我们工作的中心还是完成项目规划中 ...
- 2020BUAA软工个人项目作业
2020BUAA软工个人项目作业 17373010 杜博玮 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 学 ...
- 并发编程从零开始(六)-BlockingDeque+CopyOnWrite
并发编程从零开始(六)-BlockingDeque+CopyOnWrite 5.2 BlockingDeque BlockingDeque定义了一个阻塞的双端队列接口: 该接口继承了BlockingQ ...
- 关于stm32串口必须要学的5个串口以及串口应用和注意事项
串口是我们常用的一个数据传输接口,STM32F103系列单片机共有5个串口. 其中1-3是通用同步/异步串行接口USART(Universal Synchronous/Asynchronous Rec ...
- 21.10.14 test
题目 WOJ5078 到 WOJ5081 T1 Problem A \(\color{green}{100}\) 由于每轮要选择尽量多的边删除,所以想到无向图的生成树,因为在生成树上再加一条边就会形成 ...
- .NET 生态系统的蜕变之 .NET 6
.NET 6 是自.NET 4 框架以来生态系统看到的最大版本更新,虽然.NET Core 是2014年开始非常大的一项重大战略举措,但是.NET 6是真正的具有强大动力的非常重要的版本. 2021年 ...