LOJ #3049. 「十二省联考 2019」字符串问题

https://loj.ac/problem/3049

题意:给你\(na\)个\(A\)类串,\(nb\)个\(B\)类串,\(m\)组支配关系,求一个长度很长的串\(t_1t_2...t_k\)满足

\(t_i\)为\(A\)类串,\(t_i\)能支配一个\(B\)类串,使得该\(B\)类串为\(t_{i+1}\)的前缀。

分析:

  • 一个简单的暴力就是枚举\(A_i\)后面能接的\(A_j\)进行连边,然后拓扑序求一下最长路。
  • 很难优化,我们发现这相当于在中间塞入一个\(B\)串,然后发现如果答案不是无穷的话,每种\(B\)类串最多只用一次,那么我们可以对于每个支配关系连边,再由\(B\)串向把它当做前缀的那些\(A\)串连边,跑新图的最长路。
  • 对反串建立\(sam\),可以发现\(B\)串向\(parent\)树的一个子树上连边,倍增定位可以做到一个\(log\)。
  • 考虑\(B\)串可能大于A串的情况,这样的话就很可能两个串在同一个节点上但长度不同,我们可以对于每个\(A,B\)额外开出一个节点\(p\), \(p\rightarrow A\),\(B\rightarrow p\), \(p\)连一个前缀出来,总结点数是\(6n\)级别的吧。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <bitset>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
#define N 1200050
#define M 5000050
#define db(x) cerr<<#x<<" = "<<x<<endl
char w[N];
int n,la,lb,al[N],ar[N],bl[N],br[N],m,xx[N],yy[N];
int head[N],to[M],nxt[M],cnt,Q[N],du[N],tot,rt;
int ch[N][26],fa[N],len[N],uuz,pos[N],lst=1,f[21][N],ln[N],Lst[N];
ll g[N];
bool cmp(const int &x,const int &y) {return ln[x]==ln[y]?x<y:ln[x]>ln[y];
}
vector<int>V[N];
inline void add(int u,int v) {to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; du[v]++;
}
void insert(int x,int id) {int p=lst,np=++uuz,q,nq;len[np]=len[p]+1; lst=np;for(;p&&!ch[p][x];p=fa[p]) ch[p][x]=np;if(!p) fa[np]=rt;else {q=ch[p][x];if(len[q]==len[p]+1) fa[np]=q;else {nq=++uuz;fa[nq]=fa[q];len[nq]=len[p]+1;memcpy(ch[nq],ch[q],sizeof(ch[q]));fa[q]=fa[np]=nq;for(;p&&ch[p][x]==q;p=fa[p]) ch[p][x]=nq;}}
}
void dfs(int x) {int i;for(i=1;(1<<i)<=uuz;i++) f[i][x]=f[i-1][f[i-1][x]];for(i=head[x];i;i=nxt[i]) {f[0][to[i]]=x;dfs(to[i]);}
}
int find(int l,int r) {int p=pos[r];int i;for(i=20;i>=0;i--) if(f[i][p]&&len[f[i][p]]>=r-l+1) p=f[i][p];return p;
}
void solve() {scanf("%s",w+1);n=strlen(w+1);reverse(w+1,w+n+1);int i,j;ll ans=0;scanf("%d",&la);for(i=1;i<=la;i++) scanf("%d%d",&al[i],&ar[i]);scanf("%d",&lb);for(i=1;i<=lb;i++) scanf("%d%d",&bl[i],&br[i]);scanf("%d",&m);tot=la+lb;for(i=1;i<=la;i++) {al[i]=n-al[i]+1,ar[i]=n-ar[i]+1,swap(al[i],ar[i]);}for(i=1;i<=lb;i++) {bl[i]=n-bl[i]+1,br[i]=n-br[i]+1,swap(bl[i],br[i]);}for(i=1;i<=la;i++) ln[i]=ar[i]-al[i]+1;for(i=1;i<=lb;i++) ln[i+la]=br[i]-bl[i]+1;rt=tot+1;lst=tot+1;uuz=tot+1;for(i=1;i<=n;i++) insert(w[i]-'a',i),pos[i]=lst;for(i=rt+1;i<=uuz;i++) add(fa[i],i);dfs(rt);for(i=rt;i<=uuz;i++) head[i]=0,du[i]=0;cnt=0;for(i=1;i<=m;i++) {scanf("%d%d",&xx[i],&yy[i]);add(xx[i],yy[i]+la);}for(i=1;i<=la;i++) {int p=find(al[i],ar[i]);V[p].push_back(i);}for(i=1;i<=lb;i++) {int p=find(bl[i],br[i]);V[p].push_back(i+la);}int ee=uuz;for(i=rt+1;i<=uuz;i++) {sort(V[i].begin(),V[i].end(),cmp);int lim=V[i].size(),lst=i;Lst[i]=i;if(lim==0) continue;for(j=0;j<lim;j++) {ee++;add(ee,lst);lst=ee;if(V[i][j]<=la) add(ee,V[i][j]);else add(V[i][j],ee);}Lst[i]=lst;}for(i=rt+1;i<=uuz;i++) add(fa[i],Lst[i]);uuz=ee;int l=0,r=0;for(i=1;i<=uuz;i++) if(!du[i]) Q[r++]=i;while(l<r) {int x=Q[l++];g[x]+=(x<=la?(ar[x]-al[x]+1):0);ans=max(ans,g[x]);for(i=head[x];i;i=nxt[i]) {du[to[i]]--; g[to[i]]=max(g[to[i]],g[x]);if(!du[to[i]]) Q[r++]=to[i];}}if(r!=uuz)puts("-1");elseprintf("%lld\n",ans);cnt=0;for(i=1;i<=n;i++) pos[i]=0;for(i=1;i<=uuz;i++) {fa[i]=len[i]=head[i]=du[i]=g[i]=Q[i]=0; V[i].clear();}for(i=0;(1<<i)<=uuz;i++) for(j=rt;j<=uuz;j++) f[i][j]=0;for(i=rt;i<=uuz;i++) memset(ch[i],0,sizeof(ch[i]));return ;
}
int main() {int T;scanf("%d",&T);while(T--) solve();
}

转载于:https://www.cnblogs.com/suika/p/10666961.html

LOJ #3049. 「十二省联考 2019」字符串问题相关推荐

  1. LOJ 3049: 洛谷 P5284: 「十二省联考 2019」字符串问题

    题目传送门:LOJ #3049. 题意简述: 给定一个长度为 \(n\) 的母串 \(S\). 有 \(n_a\) 个 A 类串,都是 \(S\) 的子串,以区间的形式给出. 有 \(n_b\) 个 ...

  2. 「十二省联考 2019」皮配——dp

    题目 [题目描述] #### 题目背景 一年一度的综艺节目<中国好码农>又开始了.本季度,好码农由 Yazid.Zayid.小 R.大 R 四位梦想导师坐镇,他们都将组建自己的梦想战队,并 ...

  3. 「十二省联考 2019」希望

    Solution 题意简述:选出 k k k 个树上连通块,使得存在一个点 u u u 满足: 1. u u u 在这 k k k 个连通块的交集之中. 2.对于这 k k k 个连通块中的任意一点 ...

  4. 【十二省联考2019】字符串问题【后缀自动机】【拓扑排序】

    题意:给一个字符串 SSS,以子串的形式给出一些 A 类串和 B 类串以及 mmm 对 A 类串支配 B 类串的关系.求一个总长度最长的 A 类串序列,使得每个串都存在一个 B 类串前缀被后一个串支配 ...

  5. 【BZOJ5498】[十二省联考2019]皮配(动态规划)

    [BZOJ5498][十二省联考2019]皮配(动态规划) 题面 BZOJ 洛谷 题解 先考虑暴力\(dp\),设\(f[i][j][k]\)表示前\(i\)所学校,有\(j\)人在某个阵营,有\(k ...

  6. [十二省联考2019]春节十二响——长链剖分+堆

    题目链接: [十二省联考2019]春节十二响 可以发现每条链上的所有点都要放在不同的段里,那么最多只需要树的深度这么多段就够了. 因为这样可以保证每条链上的点可以放在不同的段中而且一个点放在这些段中一 ...

  7. 十二省联考 2019 题解

    [十二省联考2019]异或粽子 首先异或转前缀和,类似超级钢琴,将三元组 ( l , r , p ) (l,r,p) (l,r,p) 插入堆,表示 s u m [ p ] sum[p] sum[p] ...

  8. 【十二省联考2019】春节十二响

    题面 https://www.luogu.org/problem/P5290 题解 真的是我傻逼,十二省联考$day2$至今还是我的噩梦.$day1$起码一直在调可持久化$trie$树,$day2$真 ...

  9. HAOI(十二省联考)2019 qwq记

    \(\large{Day\ -1}:\) 放假了,白天大概是抱着最后一次在机房的心态复习着板子过去的.看着机房里的各位神仙丝毫不慌的颓倒是有点慌了,敲了一下多项式的板子感觉写的相当自闭,感觉AFO应该 ...

  10. 十二省联考2019酱油记

    在中考前去省选玩一趟. Day -1 对于一个还没有学会所有省选内容的初三Oier来说,这一趟真的是去打酱油的啊.但还是要认真复习. 最近几天在字符串的路上越走越远-晚上才开始复习图论.还有一大堆没有 ...

最新文章

  1. 蓝绿部署、金丝雀发布(灰度发布)、AB测试……
  2. 电商618背后的那些技术事儿
  3. 从算法+数据结构到MVC
  4. [学习笔记]矩形面积并
  5. 面试小结之Elasticsearch篇
  6. 快速连续点击两次出现相同内容的解决方法
  7. python课程与c+课程有什么不同-Python学习之二:Python 与 C 区别
  8. Mysql 8 密码策略之组件方式及ERROR 1819
  9. 使用sqlyog创建数据库
  10. linux 安卓git,在Linux系统上安装Git
  11. 怎么查询AI论文的源代码?
  12. 松露菌行业调研报告 - 市场现状分析与发展前景预测
  13. [CentOS 7] TexLive2017中kpsewhich Bug的修复
  14. vue.js手册_Vue手册:Vue.js的完整介绍
  15. OGRE实现纸娃娃系统
  16. 【JAVASCRIPT】使用ztree树,实现右键增加,修改,删除节点。带有复选框。
  17. 一图看全 · 知道创宇乌镇行
  18. 百世赴美IPO拟募7.5亿美元,“另类”大佬周韶宁迎来新冒险
  19. 2018-2019 ICPC, NEERC, Northern Eurasia Finals K. King Kog's Reception 线段树
  20. 无聊吗?写个【飞机大战】来玩吧(下篇)

热门文章

  1. 再谈微软复兴,纳德拉与库克、马斯克、皮查伊在管理上有什么不同
  2. iOS 内购最新讲解
  3. Merkle tree for non-membership proof
  4. 读论文《Toward Controlled Generation of Text》
  5. ArcGIS空间统计——点密度计算
  6. 如何以管理员身份运行powerShell
  7. 利用xpath数据解析爬取百度新闻热榜
  8. DP转HDMI方案设计/DP转HDMI/VGA方案CS5216/CS5218/CS5262方案应用参数详细对比
  9. 爬虫--初体验(获取二级网站)
  10. mysql的exception_mysqlexception