洛谷 SP7258 SUBLEX - Lexicographical Substring Search

Problem

先给你一个字符串s,后有T次询问。询问这个字符串的所有本质不同的子串中第k小的子串。

\(\mid s\mid\le9\times 10^4,T\le500\)

Solution

这也是一道SAM的模板题。

字典序第k小子串对应SAM中字典序第k小的路径。用拓扑排序计算每个状态的路径数之后,我们从SAM的根节点开始跑,类比平衡树等数据结构中的查询第k小的数这一个操作,很容易就可以找到第k小的路径。

Code

/**************************************************************
* Problem: SP7258
* Author: Vanilla_chan
* Date: 20210325
* E-Mail: Vanilla_chan@outlook.com
**************************************************************/
//预编译部分已略
namespace SAM
{
const int maxn=90010;
struct state
{
int len,link;
LL f;
map<char,int>nxt;
state operator=(const state& z)
{
len=z.len;
link=z.link;
nxt=z.nxt;
f=0;
return *this;
}
}st[maxn<<1];
int cnt=1,last=1;
void insert(const char& ch)
{
int p=last;
int cur=last=++cnt;
st[cur].len=st[p].len+1;
st[cur].f=1;
while(p&&!st[p].nxt.count(ch))
{
st[p].nxt[ch]=cur;
p=st[p].link;
}
if(!p)
{
st[cur].link=1;
}
else
{
int q=st[p].nxt[ch];
if(st[p].len+1==st[q].len)//
{
st[cur].link=q;
}
else
{
int nq=++cnt;
st[nq]=st[q];
st[nq].len=st[p].len+1;//
st[q].link=st[cur].link=nq;
while(p&&st[p].nxt[ch]==q)
{
st[p].nxt[ch]=nq;
p=st[p].link;
}
}
}
}
};
#define N 90010
LL ans;
int in[N<<1];
int l,r;
int q[N<<1];
int sze[N<<1];
void top()
{
using namespace SAM;
for(int i=1;i<=cnt;i++)
{
for(map<char,int>::iterator it=st[i].nxt.begin();it!=st[i].nxt.end();it++)
{
in[it->second]++;
}
}
l=1,r=0;
for(int i=1;i<=cnt;i++) if(in[i]==0) q[++r]=i;
for(;l<=r;l++)
{
for(map<char,int>::iterator it=st[q[l]].nxt.begin();it!=st[q[l]].nxt.end();it++)
{
in[it->second]--;
if(in[it->second]==0)
{
q[++r]=it->second;
}
}
}
for(int i=r;i>=1;i--)
{
sze[q[i]]=1;
for(map<char,int>::iterator it=st[q[i]].nxt.begin();it!=st[q[i]].nxt.end();it++)
{
sze[q[i]]+=sze[it->second];
}
}
}
void ask(int x,int k)
{
using namespace SAM;
while(k)
{
for(map<char,int>::iterator it=st[x].nxt.begin();it!=st[x].nxt.end();it++)
{
if(sze[it->second]>=k)
{
putchar(it->first);
x=it->second;
k--;
break;
}
else k-=sze[it->second];
}
}
cout<<endl;
}
string str;
int n,t,k;
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
oi::cin>>str;
for(int i=0;i<str.size();i++)
{
SAM::insert(str[i]);
}
top();
t=read();
while(t--)
{
oi::cin>>k;
ask(1,k);
}
return 0;
}

extend

注意这道题是求本质不同的,即,对于本质相同、不同位置子串,看作是一种。

接下来不妨去做一下洛谷 P3975 [TJOI2015]弦论,求对于所有子串的所有子串(不同位置的相同子串算作多个)的第k小子串。

洛谷 SP7258 SUBLEX - Lexicographical Substring Search的更多相关文章

  1. SP7258 SUBLEX - Lexicographical Substring Search

    \(\color{#0066ff}{ 题目描述 }\) 给定一个字符串,求排名第k小的串 \(\color{#0066ff}{输入格式}\) 第一行给定主串(len<=90000) 第二行给定询 ...

  2. SP7258 SUBLEX - Lexicographical Substring Search(后缀自动机)

    传送门 解题思路 首先建\(sam\),然后在拓扑序上\(dp\)一下,把每个点的路径数算出来,然后统计答案时就在自动机上\(dfs\)一下,仿照平衡树那样找第\(k\)小. 代码 #include& ...

  3. SP7258 SUBLEX - Lexicographical Substring Search - 后缀自动机,dp

    给定一个字符串,求本质不同排名第k小的子串 Solution 后缀自动机上每条路径对应一个本质不同的子串 按照 TRANS 图的拓扑序,DP 计算出每个点发出多少条路径 (注意区别 TRANS 图的拓 ...

  4. SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组

    SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...

  5. SPOJ7258 SUBLEX - Lexicographical Substring Search

    传送门[洛谷] 心态崩了我有妹子 靠 我写的记忆化搜索 莫名WA了 然后心态崩了 当我正要改成bfs排序的时候 我灵光一动 md我写的i=0;i<25;i++??? 然后 改过来就A掉了T^T ...

  6. SPOJ SUBLEX Lexicographical Substring Search - 后缀数组

    题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...

  7. spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看

    SPOJ.com - Problem SUBLEX 这么裸的一个SAM,放在了死破OJ上面就是个坑. 注意用SAM做的时候输出要用一个数组存下来,然后再puts,不然一个一个字符输出会更慢. 还有一个 ...

  8. SPOJ7258 SUBLEX - Lexicographical Substring Search(后缀自动机)

    Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...

  9. SPOJ:SUBLEX - Lexicographical Substring Search

    题面 第一行给定主串\((len<=90000)\) 第二行给定询问个数\(T<=500\) 随后给出\(T\)行\(T\)个询问,每次询问排名第\(k\)小的串,范围在\(int\)内 ...

  10. Spoj SUBLEX - Lexicographical Substring Search

    Dicription Little Daniel loves to play with strings! He always finds different ways to have fun with ...

随机推荐

  1. 非容器环境中使用Selenium,提升Chrome与ChromeDiver兼容性

    背景 在 Windows 环境下使用 Selenium 时,Chrome 浏览器版本与 ChromeDriver 版本的兼容性问题是一个常见的困扰. 由于 Chrome 频繁更新,而 ChromeDr ...

  2. factor

    factor easy_factor1 task.py from Crypto.Util.number import * from Crypto.Util.Padding import * from ...

  3. golang interface 转 string、int、float64

    interface{} interface{} 接口.interface{} 类型很多人都会混淆.interface{} 类型是没有方法的接口.由于没有 implements 关键字,所以说所有的类型 ...

  4. 【Azure Fabric Service】分享使用Visual Studio 2022发布中国区Service Fabric服务应用的办法

    问题描述 使用Visual Studio 2022如何发布Service Fabric到中国区云服务呢? 因为使用VS2022中的插件无法创建Service Fabric Cluster服务. 那么, ...

  5. StarRocks 升级注意事项

    前段时间升级了生产环境的 StarRocks,从 3.3.3 升级到了 3.3.9,期间还是踩了不少坑所以在这里记录下. 因为我们的集群使用的是存算分离的版本,也是使用官方提供的 operator 部 ...

  6. 针对于基于surging的dotnetty组件内存泄漏问题

    一.概述 前段时间客户碰到基于surging内存泄漏问题,邀请我来现场帮忙解决,对于dotnetty 我一直又爱又恨,因堆外内存DirectByteBufferChunk 中PoolChunk映射分配 ...

  7. 深度剖析 StarRocks 读取 ORC 加密文件背后的技术

    作者:vivo 互联网大数据团队 - Zheng Xiaofeng 本文介绍了StarRocks数据库如何读取ORC加密文件,包括基础概念以及具体实现方案.深入探讨了利用ORC文件的四层结构和三层索引 ...

  8. Hyperledger Fabric - 自定义createChannel命令

    前提条件 启动上一步的自定义network网络 ./network-myself.sh up 拷贝配置文件 以下文件是配置文件及相关脚本文件: mkdir configtx #创建配置文件目录 cp ...

  9. 面试官:如果某个业务量突然提升100倍QPS你会怎么做?

    "假设你负责的系统,某个业务线的QPS突然暴增100倍,你会怎么应对?" --这是上周朋友去面试,被问到一道题,他答了"加机器扩容",结果面试官眉头一皱:&qu ...

  10. 掌握Tortoise-ORM高级异步查询技巧

    title: 掌握Tortoise-ORM高级异步查询技巧 date: 2025/04/22 12:05:33 updated: 2025/04/22 12:05:33 author: cmdrago ...