CodeForces - 1037H: Security(SAM+线段树合并)
题意:给定字符串S; Q次询问,每次询问给出(L,R,T),让你在S[L,R]里面找一个字典序最小的子串,其字典序比T大。 没有则输出-1;
思路:比T字典序大,而且要求字典最小,显然就是在T的尾巴加一个很小的字符,如果不存在,则依次删去尾巴,直到“存在”。
而“存在”是指,前缀lim+一个字符‘x’后存在于[L+lim,R]中, 所以我们需要预处理出所有点的endpos,这个用线段树合并就可以了。
注意这里是每一个节点都要记录,所以和普通的启发式合并不太一样,这里需要每次新开一个节点。
#include<bits/stdc++.h>
#define rep2(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
char c[maxn]; int rt[maxn],N,tot;
struct in{
int L,R,sum;
}s[maxn*];
void ins(int &now,int L,int R,int p)
{
if(!now) now=++tot; s[now].sum++;
if(L==R) return ; int Mid=(L+R)>>;
if(p<=Mid) ins(s[now].L,L,Mid,p);
else ins(s[now].R,Mid+,R,p);
}
int merge(int x,int y)
{
if(!x||!y) return x|y;
int now=++tot;
s[now].L=merge(s[x].L,s[y].L);
s[now].R=merge(s[x].R,s[y].R);
s[now].sum=s[s[now].L].sum+s[s[now].R].sum;
return now;
}
bool query(int Now,int L,int R,int l,int r)
{
if(!Now||l>r) return false;
if(l<=L&&r>=R) return s[Now].sum;
int Mid=(L+R)>>;
if(l<=Mid&&query(s[Now].L,L,Mid,l,r)) return true;
if(r>Mid) return query(s[Now].R,Mid+,R,l,r);
return 0;
}
struct SAM{
int ch[maxn][],fa[maxn],maxlen[maxn],cnt,last;
int a[maxn],b[maxn];
void init()
{
cnt=last=;
memset(ch[],,sizeof(ch[]));
}
int add(int x,int id)
{
int np=++cnt,p=last; last=np;
ins(rt[np],,N,id);
maxlen[np]=maxlen[p]+; memset(ch[np],,sizeof(ch[np]));
while(p&&!ch[p][x]) ch[p][x]=np,p=fa[p];
if(!p) fa[np]=;
else {
int q=ch[p][x];
if(maxlen[q]==maxlen[p]+) fa[np]=q;
else {
int nq=++cnt; maxlen[nq]=maxlen[p]+;
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
while(p&&ch[p][x]==q) ch[p][x]=nq,p=fa[p];
}
}
}
void sort()
{
rep(i,,cnt) a[i]=;
rep(i,,cnt) a[maxlen[i]]++;
rep(i,,cnt) a[i]+=a[i-];
rep(i,,cnt) b[a[maxlen[i]]--]=i;
for(int i=cnt;i>=;i--) {
int x=b[i];
if(fa[x]) rt[fa[x]]=merge(rt[fa[x]],rt[x]);
}
}
}T;
int pos[maxn],Q;
void solve()
{
int L,R,len,fcy;
scanf("%d%d%s",&L,&R,c+);
len=strlen(c+);
int now=,lim=len; c[len+]='a'-;
rep(i,,len) {
if(T.ch[now][c[i]-'a']) now=T.ch[now][c[i]-'a'];
else { lim=i-; break;}
pos[i]=now;
}
fcy=-; pos[]=;
for(int i=lim;i>=&&fcy==-;i--){
for(int j=c[i+]-'a'+;j<;j++){
int v=T.ch[pos[i]][j];
if(!v) continue;
if(query(rt[v],,N,L+i,R)) {
fcy=i+; c[fcy]='a'+j;
break;
}
}
}
if(fcy==-) puts("-1");
else { rep(i,,fcy) putchar(c[i]); puts(""); }
}
int main()
{
T.init();
scanf("%s",c+); N=strlen(c+);
rep(i,,N) T.add(c[i]-'a',i);
T.sort();
scanf("%d",&Q);
while(Q--) solve();
return ;
}
CodeForces - 1037H: Security(SAM+线段树合并)的更多相关文章
- CF1037H Security——SAM+线段树合并
又是一道\(SAM\)维护\(endpos\)集合的题,我直接把CF700E的板子粘过来了QwQ 思路 如果我们有\([l,r]\)对应的\(SAM\),只需要在上面贪心就可以了.因为要求的是字典序比 ...
- 【Codeforces 1037H】Security(SAM & 线段树合并)
Description 给出一个字符串 \(S\). 给出 \(Q\) 个操作,给出 \(L, R, T\),求字典序最小的 \(S_1\),使得 \(S^\prime\) 为\(S[L..R]\) ...
- Codeforces 1276F - Asterisk Substrings(SAM+线段树合并+虚树)
Codeforces 题面传送门 & 洛谷题面传送门 SAM hot tea %%%%%%% 首先我们显然可以将所有能够得到的字符串分成六类:\(\varnothing,\text{*},s, ...
- Codeforces 700E. Cool Slogans 字符串,SAM,线段树合并,动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF700E.html 题解 首先建个SAM. 一个结论:对于parent树上任意一个点x,以及它所代表的子树内任 ...
- 洛谷P4482 [BJWC2018]Border 的四种求法 字符串,SAM,线段树合并,线段树,树链剖分,DSU on Tree
原文链接https://www.cnblogs.com/zhouzhendong/p/LuoguP4482.html 题意 给定一个字符串 S,有 q 次询问,每次给定两个数 L,R ,求 S[L.. ...
- UOJ#395. 【NOI2018】你的名字 字符串,SAM,线段树合并
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ395.html 题解 记得同步赛的时候这题我爆0了,最暴力的暴力都没调出来. 首先我们看看 68 分怎么做 ...
- loj#2059. 「TJOI / HEOI2016」字符串 sam+线段树合并+倍增
题意:给你一个子串,m次询问,每次给你abcd,问你子串sa-b的所有子串和子串sc-d的最长公共前缀是多长 题解:首先要求两个子串的最长公共前缀就是把反过来插入变成最长公共后缀,两个节点在paren ...
- 2019.02.27 bzoj4556: [Tjoi2016&Heoi2016]字符串(二分答案+sam+线段树合并)
传送门 题意:给一个字符串SSS. 有mmm次询问,每次给四个参数a,b,c,da,b,c,da,b,c,d,问s[a...b]s[a...b]s[a...b]的所有子串和s[x...y]s[x... ...
- CF700E:Cool Slogans(SAM,线段树合并)
Description 给你一个字符串,如果一个串包含两个可有交集的相同子串,那么这个串的价值就是子串的价值+1.问你给定字符串的最大价值子串的价值. Input 第一行读入字符串长度$n$,第二行是 ...
随机推荐
- 【数据结构】【计算机视觉】并查集(disjoint set)结构介绍
1.简述 在实现多图像无序输入的拼接中,我们先使用surf算法对任意两幅图像进行特征点匹配,每对图像的匹配都有一个置信度confidence参数,来衡量两幅图匹配的可信度,当confidence> ...
- NET Core3前后端分离开发框架
NET Core前后端分离快速开发框架 https://www.cnblogs.com/coldairarrow/p/11870993.html 引言 时间真快,转眼今年又要过去了.回想今年,依次开源 ...
- idea从github导入maven项目
原文地址:https://blog.csdn.net/dianyongpai3113/article/details/82784716 之后next.finish就好了
- Linux常用基础(二)
1.压缩包管理 (1)gz和bz2格式 1)gzip -- gz格式的压缩包 压缩:gzip +压缩的文件 解压缩:gunzip + 需要解压的文件 2)bzip2 -- bz2格式的压缩包 压缩:b ...
- Js迷宫游戏
<!DOCTYPE html> <html> <head> <title>MyHtml.html</title> </head> ...
- 【Mac+Appium+Python】之用 uiautomator2 启动报错
参数中添加了: automationName: Uiautomator2 运行如下: [UiAutomator2] Starting UIAutomator2 server 3.1.1 [UiAuto ...
- Linux时间日期类,压缩和解压类
一.时间日期类 1.data指令 1.基本指令 date 显示当前日期 data +%Y 显示当前年份 data +%m 显示当前月份 data +%d 显示当前天 data +%Y-%m-%d %H ...
- Lua代码编写规范
开发中,大量使用lua,暂时根据当前状况,总结相对而言较好的规范,在多人协作中可以更好的开发.交流. 介绍 该文档旨在为使用lua编写应用程序建立编码指南. 制订编码规范的目的: 统一编码标准,通用 ...
- Mysql——查看数据库,表占用磁盘大小
.查询所有数据库占用磁盘空间大小 select TABLE_SCHEMA, concat(,),' MB') as data_size, concat(,),'MB') as index_size f ...
- Kubernetes学习续之一键部署kubeadm
1.Kubernetes的架构和组件,在部署时,它的每一个组件都是一个需要被执行的.单独的二进制文件,所以不难想象,SaltStack这样的运维工具或由社区维护的脚本的功能,就是要把这些二进制文件传输 ...