[十二省联考2019]字符串问题 后缀自动机 + 拓扑排序 + 最长路 + 倍增

题目描述:
给定一个长串 $S$,给定若干 $S$ 的子串 $a_{i}$, $b_{i}$,再给出一些 $a$ 串和 $b$ 串的支配关系.
构造一个长度最长的字符串,使得:
字符串只由 $a_{i}$ 组成.
当且仅当 $a_{i}$ 所支配的一个串 $b_{i}$ 为 $a_{j}$ 的前缀,才可将 $a_{j}$ 连到 $a_{i}$ 后面.


首先,对于求前缀,我们可以对 $S$ 的反串建立后缀自动机,这样每个 $f_{i}$ 将会转移到当前串的一个前缀,而不是后缀.

第一步,先将所有的 $a$串和$b$串都定位到后缀自动机上.
对于这一步,我们使用倍增算法.

第二部,我们将支配边进行连边(即再后缀树中对应的点和点).

顺着后缀树中的边和支配边进行转移即可.
细节部分看一下代码.

 

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue> 
#include <vector> 
#define setIO(s) freopen(s".in","r",stdin)// ,freopen(s".out","w",stdout) 
#define maxn 1500001 
using namespace std;
char str[maxn]; 
int debug; 
int length,na,nb,m;  
namespace SAM{#define N 29 #define ll long long #define L l=length-l+1#define R r=length-r+1 int last,tot;     vector<int>ed[maxn];        int la[maxn],ra[maxn],h[maxn];     int ch[maxn][N],dis[maxn]; int f[maxn],trace[maxn],mk[maxn],pos[maxn];  int F[24][maxn];     int head[maxn],to[maxn],nex[maxn],edges; int ge[maxn]; int vis[maxn]; int trc; queue<int>Q; int du[maxn]; long long DP[maxn]; int idx[maxn]; int cmp(int i,int j){   if(h[i]==h[j]) return i>j; return h[i]<h[j];         }void add(int u,int v){nex[++edges] = head[u],head[u]=edges,to[edges]=v;    mk[edges]=0;   //if(!debug) printf("%d %d\n",u,v); }//SAM of S void ins(int c,int i){          int np = ++tot, p = last; last = np; dis[np] = i; while(p && !ch[p][c]) ch[p][c] = np, p = f[p];     if(!p) f[np] = 1;else {      int q = ch[p][c];	if(dis[q] == dis[p] + 1) f[np] = q;else {int nq = ++tot; dis[nq] = dis[p] + 1; memcpy(ch[nq],ch[q],sizeof(ch[q])); f[nq] = f[q], f[np] = f[q] = nq;   while(p && ch[p][c] == q) ch[p][c] = nq,p = f[p]; }}trace[i] = np; } void DFS(int u){           F[0][u]=f[u];for(int i=1;i<24;++i) F[i][u]=F[i-1][F[i-1][u]];  int sz=ed[u].size(); for(int i=0;i<sz;++i) DFS(ed[u][i]); ed[u].clear(); }    void build(){int l,r;scanf("%d",&na);for(int i=1;i<=na;++i){scanf("%d%d",&l,&r); L;R; swap(l,r); la[i]=l,ra[i]=r,h[i]=r-l+1;   } scanf("%d",&nb); for(int i=1;i<=nb;++i)  {scanf("%d%d",&l,&r); L;R; swap(l,r); la[i+na]=l,ra[i+na]=r,h[i+na]=r-l+1;  }for(int i=2;i<=tot;++i) ed[f[i]].push_back(i); trc=tot; DFS(1);      for(int i=1;i<=na+nb;++i) {int p=trace[ra[i]];  for(int j=23;j>=0;--j) if(dis[F[j][p]] >= h[i]) p=F[j][p];    if(dis[p]==h[i]) pos[i]=p;             else ed[p].push_back(i); }}void sol(){int nn=tot; for(int i=2;i<=nn;++i){   if(ed[i].size()==0){       add(f[i],i);           continue; }int p=0;                int sz=ed[i].size();        for(int j=0;j<sz;++j) ge[++p]=ed[i][j];           //  sort(ge+1,ge+1+p,cmp);                           //将该点对应字符串按长度排序       int lst=f[i]; for(int j=1;j<=p;++j) {            add(lst,++tot); dis[tot] = h[ge[j]];   pos[ge[j]]=tot;  lst=tot; }add(pos[ge[p]],i); ed[i].clear(); }}void get(){int a,b; scanf("%d%d",&a,&b); add(pos[a],pos[b+na]);   mk[edges]=1;  }     void solve(){Q.push(1); du[1]=0; long long  ans=0; for(int i=1;i<=edges;++i) ++du[to[i]]; while(!Q.empty()){int u=Q.front(); Q.pop(); for(int i=head[u];i;i=nex[i]){--du[to[i]];                       long long ed=DP[u]+dis[to[i]]-(mk[i]?0:dis[u]); DP[to[i]]=max(DP[to[i]],ed);                           if(du[to[i]]==0) Q.push(to[i]); }}    for(int i=1;i<=tot;++i) if(du[i]!=0) {printf("-1\n"); return; }for(int i=1;i<=na;++i)  ans=max(ans,DP[pos[i]]);      printf("%lld\n",ans);     }void init(){for(int i=1;i<=tot;++i) DP[i]=0; for(int i=1;i<=tot;++i) dis[i]=0;    for(int i=1;i<=edges;++i) mk[i]=0;        for(int i=1;i<=tot;++i) head[i]=0;  for(int i=0;i<=tot;++i) du[i]=0;      for(int i=1;i<=trc;++i) for(int j=0;j<=22;++j) F[j][i]=0; for(int i=1;i<=trc;++i) memset(ch[i],0,sizeof(ch[i]));     last=tot=1,edges=0;     }
};
int main(){//setIO("string9");   int T; scanf("%d",&T);   while(T--){    debug=T; SAM::last=SAM::tot=1;            scanf("%s",str+1),length=strlen(str+1);             for(int i=length;i;--i) SAM::ins(str[i]-'a',length-i+1);          SAM::trc=SAM::tot; SAM::build();   SAM::sol(); scanf("%d",&m); for(int i=1;i<=m;++i) SAM::get();     SAM::solve(); SAM::init(); }return 0; 
}

  

转载于:https://www.cnblogs.com/guangheli/p/10679544.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式事务2PC、3PC模型

工作中使用最多的是本地事务&#xff0c;但是在对单一项目拆分为 SOA、微服务之后&#xff0c;就会牵扯出分布式事务场景 文章以分布式事务为主线展开说明&#xff0c;并且针对 2PC、3PC 算法进行详细的讲解&#xff0c;最后通过一个 Demo 来更深入掌握分布式事务&#xff0c;…

c# datatable用法总结

在项目中经常用到DataTable,如果DataTable使用得当&#xff0c;不仅能使程序简洁实用&#xff0c;而且能够提高性能&#xff0c;达到事半功倍的效果&#xff0c;现对DataTable的使用技巧进行一下总结。 一、DataTable简介 (1)构造函数 DataTable() 不带参数初始化DataT…

Python学习之路——装饰器

开放封闭原则&#xff1a;不改变调用方式与源代码上增加功能 1.不能修改被装饰对象(函数)的源代码&#xff08;封闭&#xff09; 2.不能更改被修饰对象(函数)的调用方式&#xff0c;且能达到增加功能的效果&#xff08;开放&#xff09;View Code装饰器 # 把要被装饰的函数作为…

通断时间面积法

背景&#xff1a; 来 源&#xff1a; 通断时间面积法是入选《供热计量技术规程》JGJ173-2009的一种热量分摊计量方法实现分户计量的一种计量方法。由清华大学建筑节能研究中心江亿院士提出。 简 称 ( 俗称 )&#xff1a;&#xff08;1&#xff09;“时温法”&#xff08;2&a…

C++ std::move()和完美转发

std::move()、std::forward<T>、模板类型推断分析 引用折叠原则和完美转发是有联系的&#xff0c;可以说后者是基于前者的某些特性实现的&#xff0c;具体来看一下。 要理解完美转发&#xff0c;需要了解两个知识点&#xff1a; 引用折叠原则&#xff08;Reference colla…

线面要素类相互转换-原创

一、线转面的步骤 1、线几何属性转面几何属性ArcToolbox-Data Management Tools-Features-Feature To polygon&#xff0c;此过程只是将几何属性做了转换&#xff0c;得到的是属性信息丢失了的面t_L_HDBX_FeatureToPolygon1 2、 在ArcMap中将t_L_HDBX_FeatureToPolygon1全选&a…

SEO网站标题怎么优化

经过前两天发的两篇原创文章被加精之后&#xff0c;我的热情是一发不可收拾&#xff0c;忍不住又想写点干货给大家分享&#xff01;今天分析一下网站标题如何设置之SEO技巧。通过标题就可以看出&#xff0c;今天是讲网站标题如何设置&#xff0c;为什么要写这个呢&#xff1f;因…

Redis淘汰删除策略

Redis淘汰删除策略Redis淘汰删除策略6种淘汰Key策略3种删除过期键策略定时删除惰性删除定期删除其他模块的淘汰处理RDB 快照持久化创建载入AOF 只追加持久化写入重写主从复模式下对过期键的处理6种淘汰Key策略Redis中通过maxmemory参数来设定内存的使用上限&#xff0c;当Redis…

MySQL NDB Cluster

1. MySQL Cluster 是一种技术&#xff0c;该技术允许在无共享的系统中部署“内存中”数据库的 Cluster 。通过无共享体系结构&#xff0c;系统能够使用廉价的硬件&#xff0c;而且对软硬件无特殊要求。此外&#xff0c;由于每个组件有自己的内存和磁盘&#xff0c;不存在单点故…

《上邪》诗解

上邪&#xff01;①   我欲与君相知②&#xff0c; 长命③无绝衰。   山无陵④&#xff0c; 江水为竭&#xff0c;   冬雷震震⑤&#xff0c; 夏雨雪⑥ &#xff0c;   天地合⑦ &#xff0c; 乃敢⑧与君绝&#xff01;天啊&#xff01;我愿与你相爱&#xff0c;让我们…

win8 关于Adobe CS6系列软件Patch覆盖失败的问题(Photoshop CS6、Adobe Illustrator CS6、Adobe Fireworks CS6)...

我在Adobe文件夹下安装了Photoshop CS6和 Adobe Illustrator CS6&#xff0c;结果当我为AI覆盖Path文件后&#xff0c;我发现PS和AI全部都打不开了。反复覆盖还是没用。 不过很奇怪fireworks Cs6能用。FW我没有跟PS、AI装在同一个文件夹下。 我想难道是安装目录的问题&#xff…

获取Spring容器管理的Bean工具类

很多时候我们在一些不受spring管理的类中需要用到spring管理的Bean&#xff0c;那么这个时候可以使用如下工具类从spring容器中获取相关的Bean实例。 Component public class SpringApplicationContextUtils implements ApplicationContextAware {private static final Logger …

mysql - 内存表使用总结

部分转载&#xff1a;https://blog.csdn.net/hemeinvyiqiluoben/article/details/51222951?utm_mediumdistribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id&depth_1-utm_sourcedistribute.…

《集体智慧编程》——第一章导读

为什么80%的码农都做不了架构师&#xff1f;>>> 什么是集体智慧 其含义是指&#xff1a;为了长早新的想法&#xff0c;而将一群人的行为、偏好或思想组合在一起。 完成这项工作的一种最为基础的方法&#xff0c;便是使用调查问卷或普查。从一大群人中搜集的答案可…

使用spring的@autowired注解,无法实例化dao

首先理解spring的注解注入dao接口的目的是什么&#xff0c;是为了接口不用进行实例化就可以被任何一个类去调用 我昨天下午就是发现&#xff0c;不同的类&#xff0c;一模一样的注解&#xff0c;为什么前面的类可以使用注解调用mapper的sql查询&#xff0c;但是 第二个类死活无…

大括号之谜:C++的列表初始化语法解析

转载&#xff1a; https://segmentfault.com/a/1190000039362151 摘要&#xff1a;有朋友在使用std::array时发现一个奇怪的问题&#xff1a;当元素类型是复合类型时&#xff0c;编译通不过。 有朋友在使用std::array时发现一个奇怪的问题&#xff1a;当元素类型是复合类型时&a…

在Mono 2.8上部署ASP.NET MVC 2

Mono 2.8发布&#xff1a;C#4.0和更好的性能&#xff0c;我们知道Mono 2.8对ASP.NET MVC 2的完全支持&#xff0c;下面我们就来测试下在Mono 2.8上部署ASP.NET MVC 2应用程序。我的环境是Opensuse 11.3,通过以下命令部署好Mono 2.8的开发环境&#xff0c;之所以说是开发环境是同…

ASP.NET C# 数字格式化输出

int a 12345678; //格式为sring输出 Label1.Text string.Format("asdfadsf{0}adsfasdf",a); Label2.Text "asdfadsf"a.ToString()"adsfasdf"; Label1.Text string.Format("asdfadsf{0:C}adsfasdf",a);//asdfadsf&#xffe5;1,234…

gdb调试时,Program received signal SIGPIPE, Broken pipe.

今天在gdb调试时&#xff0c;发现总是出现Program received signal SIGPIPE, Broken pipe&#xff0c;搜索了网上的资料&#xff0c;发现是在调试时&#xff0c;接收到了SIGPIPE这个signal信号导致调试被中断。 By default, gdb captures SIGPIPE of a process and pauses it.…

看到一个暴强的翻译,闲的蛋疼,写个c#版的

在豆瓣上看到一篇关于拿破仑的翻译&#xff0c;文科生的翻译有几段相当传神&#xff0c;不得不佩服汉语的强大。有好事者还用程序语言实现了一下&#xff0c;现已有java、python和html的版本&#xff0c;我也来写个渺小的C#版本&#xff0c;运行结果和java版是一致的&#xff0…