题目分析:

建出后缀自动机,然后把A串用倍增定位到后缀自动机上,再把B串用倍增定位到后缀自动机上。

SAM上每个点上的A串根据长度从小到大排序,建点,依次连边。

再对于SAM上面每个点,连到儿子的边,同时连到儿子的最小A串的边。

对于m组关系,建立x连到y定位到的SAM上的点的边,同时连y所能匹配的到定位到的点上的最短字符串的边。

然后跑拓扑排序就行了。

代码:

 #include<bits/stdc++.h>
using namespace std; const int maxn = ; char str[maxn];
int na,nb,len,m;
int la[maxn],ra[maxn],lb[maxn],rb[maxn]; int lst=,nxt[maxn<<][],fa[maxn<<],num=,maxlen[maxn<<],st[maxn];
int lk[maxn],bh[maxn],maxnum;
vector<pair<int,int> > g[maxn*];
vector<int> chain[maxn<<];
int in[maxn*];
long long dis[maxn*]; int RMQ[maxn<<][],nowmax; void buildRMQ(){
RMQ[][] = ;
for(int i=;i<=num;i++) RMQ[i][] = fa[i];
for(int k=;(<<k)<=num;k++){
nowmax = k;
for(int i=;i<=num;i++) RMQ[i][k] = RMQ[RMQ[i][k-]][k-];
}
} int findhhh(int spp,int len){
for(int i=nowmax;i>=;i--)if(maxlen[RMQ[spp][i]]>len) spp=RMQ[spp][i];
return spp;
} void init(){
for(int i=;i<=num;i++) for(int j=;(<<j)<=num;j++)RMQ[i][j] = ;
for(int i=;i<=num;i++){
for(int j=;j<;j++)nxt[i][j] = ;
fa[i] = ; maxlen[i] = ;
chain[i].clear();
}
for(int i=;i<=len;i++) st[i] = ;
for(int i=;i<=nb;i++)lk[i] = ;
for(int i=;i<=na;i++) bh[i] = ;
for(int i=;i<=maxnum+;i++)g[i].clear(),in[i] = ;
lst = ; num = ; maxnum = ;
} queue<int> que;
void topu(){
int sz = ;
for(int i=;i<=maxnum+;i++) dis[i] = -1e18;
for(int i=;i<=maxnum+;i++)
if(!in[i]) que.push(i),sz++;
dis[] = ;
while(!que.empty()){
int zz = que.front(); que.pop();
for(int i=;i<g[zz].size();i++){
int to = g[zz][i].first; in[to]--;
if(!in[to]) sz++,que.push(to);
dis[to] = max(dis[to],dis[zz]+g[zz][i].second);
}
}
if(sz != maxnum+) puts("-1");
else printf("%lld\n",dis[maxnum+]);
} void addedge(int from,int to,int w){
g[from].push_back(make_pair(to,w));
in[to]++;
} void ins(int now){
int np = ++num,p=lst; maxlen[np] = maxlen[lst]+;
st[len-now-] = np;
for(;p&&!nxt[p][str[now]-'a'];p = fa[p]) nxt[p][str[now]-'a'] = np;
if(!p) fa[np] = ;
else{
int q = nxt[p][str[now]-'a'];
if(maxlen[q] == maxlen[p]+) fa[np] = q;
else{
int nq = ++num; maxlen[nq] = maxlen[p]+;
for(int i=;i<;i++) nxt[nq][i] = nxt[q][i];
fa[nq] = fa[q];
fa[q] = nq; fa[np] = nq;
for(;p&&nxt[p][str[now]-'a']==q;p=fa[p])nxt[p][str[now]-'a']=nq;
}
}
lst = np;
} void findpos(int now,int dt,int pp){
if(chain[now].size() == ) return;
int l = ,r = chain[now].size()-;
while(l < r){
int mid = (l+r)/;
if(ra[chain[now][mid]]-la[chain[now][mid]]>=pp) r = mid;
else l = mid+;
}
l = chain[now][l];
if(ra[l]-la[l]<pp) return;
addedge(bh[dt],bh[l],ra[dt]-la[dt]+);
} int cmp(int alpha,int beta){
if(ra[alpha]-la[alpha] < ra[beta]-la[beta]) return ;
else return ;
} void read(){
scanf("%s",str);
len = strlen(str);
scanf("%d",&na);
for(int i=;i<=na;i++) scanf("%d%d",&la[i],&ra[i]);
for(int i=;i<=na;i++)la[i]=len-la[i],ra[i]=len-ra[i],swap(la[i],ra[i]);
scanf("%d",&nb);
for(int i=;i<=nb;i++) scanf("%d%d",&lb[i],&rb[i]);
for(int i=;i<=nb;i++)lb[i]=len-lb[i],rb[i]=len-rb[i],swap(lb[i],rb[i]);
for(int i=len-;i>=;i--) ins(i);
buildRMQ();
for(int i=;i<=num;i++){addedge(fa[i],i,);} for(int i=;i<=na;i++){
int ym = findhhh(st[ra[i]],ra[i]-la[i]);
chain[ym].push_back(i);
}
for(int i=;i<=num;i++) sort(chain[i].begin(),chain[i].end(),cmp);
maxnum = num;
for(int i=;i<=num;i++)
for(int j=;j<chain[i].size();j++) bh[chain[i][j]] = ++maxnum; for(int i=;i<=num;i++)
if(chain[i].size())addedge(fa[i],bh[chain[i][]],);
for(int i=;i<=num;i++){
for(int j=;j<(int)chain[i].size()-;j++)
addedge(bh[chain[i][j]],bh[chain[i][j+]],);
}
for(int i=;i<=na;i++) addedge(,bh[i],);
for(int i=;i<=na;i++) addedge(bh[i],maxnum+,ra[i]-la[i]+); for(int i=;i<=nb;i++){
int ym = findhhh(st[rb[i]],rb[i]-lb[i]);
lk[i] = ym;
}
scanf("%d",&m);
for(int i=;i<=m;i++){
int x,y; scanf("%d%d",&x,&y);
addedge(bh[x],lk[y],ra[x]-la[x]+);
findpos(lk[y],x,rb[y]-lb[y]);
}
} int main(){
//freopen("1.in","r",stdin);
int Tmp; scanf("%d",&Tmp);
while(Tmp--){
init();
read();
topu();
}
return ;
}

LOJ3049 [十二省联考2019] 字符串问题 【后缀自动机】【倍增】【拓扑排序】的更多相关文章

  1. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

  2. 洛谷.5284.[十二省联考2019]字符串问题(后缀自动机 拓扑 DP)

    LOJ BZOJ 洛谷 对这题无话可说,确实比较...裸... 像dls说的拿拓扑和parent树一套就能出出来了... 另外表示BZOJ Rank1 tql... 暴力的话,由每个\(A_i\)向它 ...

  3. [LOJ3049] [十二省联考 2019] 字符串问题

    题目链接 LOJ:https://loj.ac/problem/3049 洛谷:https://www.luogu.org/problemnew/show/P5284 BZOJ:https://www ...

  4. 洛谷P5284 [十二省联考2019]字符串问题 [后缀树]

    传送门 思路 设\(dp_i\)表示以\(i\)结尾的\(A\)串,能达到的最长长度. 然后发现这显然可以\(i\)往自己控制的\(k\)连边,\(k\)往能匹配的\(j\)连边,就是个最长路,只要建 ...

  5. 洛谷P5284 [十二省联考2019]字符串问题(SAM+倍增+最长路)

    题面 传送门 题解 首先,我们把串反过来,那么前缀就变成后缀,建一个\(SAM\).我们发现一个节点的后缀是它的所有祖先 那么我们是不是直接按着\(parent\)树建边就可以了呢? 显然不是.我们假 ...

  6. 【BZOJ5496】[十二省联考2019]字符串问题(后缀树)

    [BZOJ5496][十二省联考2019]字符串问题(后缀树) 题面 BZOJ 洛谷 题解 首先显然可以把具有支配关系的串从\(A\)到\(B\)连一条有向边,如果\(B_i\)是\(A_j\)的前缀 ...

  7. Luogu P5284 [十二省联考2019]字符串问题

    好难写的字符串+数据结构问题,写+调了一下午的说 首先理解题意后我们对问题进行转化,对于每个字符串我们用一个点来代表它们,其中\(A\)类串的点权为它们的长度,\(B\)类串的权值为\(0\) 这样我 ...

  8. P5284 [十二省联考2019]字符串问题

    这是一道涵盖了字符串.图论.数据结构三个方面的综合大题. 把这道题放在D1T2的人应该拖出去打 前置芝士 首先,您至少要会topsort. 其次,如果您只想拿个暴力分,字符串Hash就足够了:如果您想 ...

  9. 【题解】Luogu P5284 [十二省联考2019]字符串问题

    原题传送门 我用sa做的本题 (码量似乎有点大) 先对原串建sa 考虑如何建图: 从大到小枚举长度len 先将height中等于len的两个位置在并查集合并起来,将lst也合并(lst是链表) 再将长 ...

随机推荐

  1. 阿里云ECS,Ubuntu Server 16.04安装图形界面远程控制

    最近阿里云有新用户免费体验6个月的活动,虽说是免费体验,但是还是要买个它们的产品才行,我就花9.9买了个最便宜的,然后就获得了一个乞丐版的ECS服务器,配置是1核内存1G.系统装的是Ubuntu Se ...

  2. flutter SnackBar 底部消息提示

    具有可选操作的轻量级消息提示,在屏幕的底部显示 文档:https://api.flutter.dev/flutter/material/SnackBar-class.html demo: import ...

  3. python3以post方式提交数据

    # !/usr/bin/python # encoding:utf-8 import requests #下面替换成您的数据 postdata={'name':'xiaochong'} r=reque ...

  4. TCP和TLS/SSL会话细节

    TCP数据段格式说明TCP建立连接和断开连接细节Https如何保证通信安全一次Https网络请求通信细节网络数据包分析工具wireshark的使用问题:SYN.ACK.FIN具体含义是什么?TCP建立 ...

  5. Linux的桌面虚拟化技术KVM(五)——virsh常用命令

    Linux的桌面虚拟化技术KVM(一)——新建KVM虚拟机 Linux的桌面虚拟化技术KVM(二)——远程桌面管理 Linux的桌面虚拟化技术KVM(三)——KVM虚拟机克隆和快照 Linux的桌面虚 ...

  6. Elasticsearch集成Hadoop最佳实践.pdf(内含目录)

    Elasticsearch服务器开发(第2版) 介绍: ElasticSearch是一个开源的分布式搜索引擎,具有高可靠性,支持非常多的企业级搜索用例.ElasticsearchHadoop作为一个完 ...

  7. Error:java: 发现警告, 但指定了 -Werror

    最近在使用IntelliJ IDEA编译Apache Guacamole Web项目时,遇到了一个罕见的bug:"Error:java: 发现警告, 但指定了 -Werror",见 ...

  8. expect 实现自动交互脚本

    1. 说明 在编写脚本时,可能会遇到需要在另一台主机上执行一个命令,或者在本机拷贝另一台主机内的一个文件.如果两台主机之间没有做互信,就会牵扯到用户输入密码的交互过程,这对编写自动脚本来说, 就行不通 ...

  9. 删除SQL约束的方法

    在SQL数据库中,如果需要删除表约束,应该如何操作呢?下面就将为您介绍删除SQL表约束的方法,供您参考,希望对您有所帮助. --1)禁止所有表约束的SQL select 'alter table '+ ...

  10. 【Leetcode_easy】933. Number of Recent Calls

    problem 933. Number of Recent Calls 参考 1. Leetcode_easy_933. Number of Recent Calls; 完