CF666E 【Forensic Examination】
每天一道\(SAM\)真是非常开心
一看就是广义\(SAM\)+线段树合并了
我们存好\(S\)串每一个前缀的终点,之后在\(parent\)树上倍增找到表示\(S[l,r]\)这个子串的节点,我们用线段树合并维护好\(endpos\)集合,查一个区间最大值就好了
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 2000005
#define M 10000005
#define re register
#define LL long long
#define mp std::make_pair
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
typedef std::pair<int,int> pii;
struct E{int v,nxt;}e[maxn];
char S[maxn];
int len[maxn],fa[maxn],son[maxn][26],endpos[maxn],to[maxn],head[maxn],rt[maxn];
int f[maxn][22],deep[maxn],loog[maxn];
int n,m,Q,__,num,lst=1,cnt=1,tot;
int l[M],r[M],sum[M],d[M];
inline void add(int x,int y){e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
inline void pushup(int x) {
if(sum[l[x]]>=sum[r[x]]) sum[x]=sum[l[x]],d[x]=d[l[x]];
else sum[x]=sum[r[x]],d[x]=d[r[x]];
}
int change(int now,int x,int y,int pos) {
if(!now) now=++tot;
if(x==y) {sum[now]++;d[now]=x;return now;}
int mid=x+y>>1;
if(pos<=mid) l[now]=change(l[now],x,mid,pos);
else r[now]=change(r[now],mid+1,y,pos);
pushup(now);
return now;
}
int merge(int a,int b,int x,int y) {
if(!a) return b;if(!b) return a;
int root=++tot;
if(x==y) {sum[root]=sum[a]+sum[b],d[root]=x;return root;}
int mid=x+y>>1;
l[root]=merge(l[a],l[b],x,mid),r[root]=merge(r[a],r[b],mid+1,y);
pushup(root);
return root;
}
inline void ins(int c,int o) {
int p=++cnt,f=lst; lst=p;
len[p]=len[f]+1;
if(!o) to[++__]=p;
else rt[p]=change(rt[p],1,m,o);
while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
if(!f) {fa[p]=1;return;}
int x=son[f][c];
if(len[f]+1==len[x]) {fa[p]=x;return;}
int y=++cnt;
len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
for(re int i=0;i<26;i++) son[y][i]=son[x][i];
while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
}
void dfs(int x) {
for(re int i=head[x];i;i=e[i].nxt)
deep[e[i].v]=deep[x]+1,dfs(e[i].v),rt[x]=merge(rt[x],rt[e[i].v],1,m);
}
pii query(int now,int x,int y,int lx,int ry)
{
if(lx<=x&&ry>=y) return mp(sum[now],d[now]);
int mid=x+y>>1;
if(ry<=mid) return query(l[now],x,mid,lx,ry);
if(lx>mid) return query(r[now],mid+1,y,lx,ry);
pii a=query(l[now],x,mid,lx,ry),b=query(r[now],mid+1,y,lx,ry);
if(a.first>=b.first) return a; return b;
}
int main()
{
scanf("%s",S+1);n=strlen(S+1);
for(re int i=1;i<=n;i++) ins(S[i]-'a',0);
scanf("%d",&m);
for(re int i=1;i<=m;i++)
{
scanf("%s",S+1);n=strlen(S+1);lst=1;
for(re int j=1;j<=n;j++) ins(S[j]-'a',i);
}
for(re int i=2;i<=cnt;i++) add(fa[i],i);
deep[1]=1,dfs(1);
for(re int i=1;i<=cnt;i++) f[i][0]=fa[i];
for(re int i=2;i<=cnt;i++) loog[i]=loog[i>>1]+1;
for(re int j=1;j<=loog[cnt];j++)
for(re int i=1;i<=cnt;i++)
f[i][j]=f[f[i][j-1]][j-1];
scanf("%d",&Q);
int x,y,L,R;
while(Q--)
{
scanf("%d%d%d%d",&x,&y,&L,&R);
int Len=R-L+1;
int now=to[R];
for(re int i=loog[deep[now]];i>=0;--i)
if(f[now][i]&&len[f[now][i]]>=Len) now=f[now][i];
pii ans=query(rt[now],1,m,x,y);
if(ans.first) printf("%d %d\n",ans.second,ans.first);
else printf("%d ",x),puts("0");
}
return 0;
}
CF666E 【Forensic Examination】的更多相关文章
- 【CF666E】Forensic Examination 广义后缀自动机+倍增+线段树合并
[CF666E]Forensic Examination 题意:给你一个字符串s和一个字符串集合$\{t_i\}$.有q个询问,每次给出$l,r,p_l,p_r$,问$s[p_l,p_r]$在$t_l ...
- 【CF666E】Forensic Examination(后缀自动机,线段树合并)
[CF666E]Forensic Examination(后缀自动机,线段树合并) 题面 洛谷 CF 翻译: 给定一个串\(S\)和若干个串\(T_i\) 每次询问\(S[pl..pr]\)在\(T_ ...
- 【Codeforces666E】Forensic Examination 后缀自动机 + 线段树合并
E. Forensic Examination time limit per test:6 seconds memory limit per test:768 megabytes input:stan ...
- CF 666E Forensic Examination 【SAM 倍增 线段树合并】
CF 666E Forensic Examination 题意: 给出一个串\(s\)和\(n\)个串\(t_i\),\(q\)次询问,每次询问串\(s\)的子串\(s[p_l:p_r]\)在串\(t ...
- 【AR实验室】mulberryAR : ORBSLAM2+VVSION
本文转载请注明出处 —— polobymulberry-博客园 0x00 - 前言 mulberryAR是我业余时间弄的一个AR引擎,目前主要支持单目视觉SLAM+3D渲染,并且支持iOS端,但是该引 ...
- 【.net 深呼吸】细说CodeDom(1):结构大观
CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...
- 【Machine Learning】KNN算法虹膜图片识别
K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
- 【前端性能】高性能滚动 scroll 及页面渲染优化
最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
随机推荐
- layui 数据返回但是table表格未渲染出来的问题
最近蜂鸟速驾项目用layui框架,table进行表格渲染 控制台打印发现有数据,但是table.render渲染不出来,后来发现是数据已经返回但是页面元素未加载完成的缘故,用setTimeout定时器 ...
- linux运维配置讲解--sshd-config
文件配置: 1, /etc/ssh/sshd_config ssh配置文件 2, /etc/shadow 密码文件 3, /etc/sudoers 授权用户管理文件 4, /etc/issue 系统信 ...
- arcgis影像批量裁剪代码
# -*- coding:utf-8 -*- # Name: ExtractByMask_Ex_02.py # Description: Extracts the cells of a raster ...
- 基于 CentOS 搭建 WordPress 个人博客
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 腾讯云提供了开发者实验室帮助用户搭建 WordPress 个人博客,教程内容如下,用户可以点击开发者实验室快速上机完成实验. 准备 LNMP ...
- gcc链接非标准(non-standard)命名库
标准命名库: -lnamespace 标准链接库以lib开头, 并以so/a结尾. example gcc test.c -o test -L. -lhello 非标准命名库: -l:libname ...
- bzoj 4543: [POI2014]Hotel加强版
Description 给出一棵树求三元组 \((x,y,z)\,,x<y<z\) 满足三个点两两之间距离相等,求三元组的数量 Solution 考虑暴力 \(DP\) 设 \(f[i][ ...
- Bitmap图片查看器
在Android 应用中使用assets目录下存放的资源文件,assets目录下存放的资源代表应用无法直接访问的原生资源,应用程序通过AssetManager以二 进制流的形式来读取资源.此应用是查看 ...
- 网页设计,Access入门 2010,语文
Access入门 2010(select查询) order by(按升序排列)?+desc(按降序排列) group by(进行分组,下一行只能用having) sum(数值总数)?+as?(新字段的 ...
- 08.详细说明关键字new
关键字new有两个使用方法: (1).实例化对象 (2).显示的隐藏父类中的同名方法. 来自为知笔记(Wiz)
- DJango小总结一
views.py def func(request): # 包含所有的请求数据 ... ...