所有子串,一眼 \(\text{SAM}\)。

从根开始一直往下走,走到任何一个点都代表一个子串。维护 \(sm\) 表示每个子串有几个(\(t=0\) 就当一个),可以用树形 \(dp\) 跳后缀链接树,然后暴力跑 \(\text{SAM}\) 即可。

当然我们发现这样时间复杂度会爆炸,因为第二部分是个 \(TAG\),因此用 \(cnt\) 记录每个节点能走到的所有节点的 \(sm\) 之和,这样就能少判断很多情况。

时间复杂度 \(O(26n)\)。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
int k,t,ans[N],len;
struct SAM{
int sm[N],ln[N],sz[N];
int id,tl,tr[N][26],pr[N];
vector<int>g[N];int cnt[N];
SAM(){pr[0]=-1;}
void cpy(int x,int y){
for(int i=0;i<26;i++)
tr[x][i]=tr[y][i];
pr[x]=pr[y];ln[x]=ln[y];
}void add(int x){
ln[++id]=ln[tl]+1;
int p=tl;tl=id;
while(~p&&!tr[p][x])
tr[p][x]=id,p=pr[p];
if(p<0){
sm[tl]++;
return;
}int u=p,v=tr[p][x];
if(ln[u]+1==ln[v]){
pr[id]=v;
sm[tl]++;
return;
}cpy(++id,v);
ln[id]=ln[u]+1;
pr[v]=pr[id-1]=id;
while(~p&&tr[p][x]==v)
tr[p][x]=id,p=pr[p];
sm[tl]++;
}void dfs(int x){
for(int i=0;i<g[x].size();i++)
dfs(g[x][i]),sm[x]+=sm[g[x][i]];
}void find(int x){
if(k<=0) return;
for(int i=0;i<26;i++){
int y=tr[x][i];
if(!y) continue;
if(!cnt[y]){
int p=k;ans[++len]=i;
k-=sm[y];find(y);
if(k<=0) return;
cnt[y]=p-k;len--;
}else if(k<=cnt[y]){
ans[++len]=i;
k-=sm[y];find(y);
return;
}else k-=cnt[y];
}
}void jb(){
for(int i=1;i<=id;i++)
g[pr[i]].push_back(i);
}
}sam;char s[N];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>s>>t>>k;
for(int i=0;s[i];i++)
sam.add(s[i]-'a');
sam.jb();
if(t) sam.dfs(0);
else for(int i=1;i<=sam.id;i++) sam.sm[i]=1;
sam.find(0);
for(int i=1;i<=len;i++)
cout<<(char)(ans[i]+'a');
return 0;
}//man!what can I say!

[TJOI2015] 弦论 题解的更多相关文章

  1. 洛谷 P3975 / loj 2102 [TJOI2015] 弦论 题解【后缀自动机】【拓扑排序】

    后缀自动机入门. 题目描述 为了提高智商,ZJY 开始学习弦论. 这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为 \(n\) 的字符串,求出它的第 \ ...

  2. BZOJ3998:[TJOI2015]弦论——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3998 https://www.luogu.org/problemnew/show/P3975 对于 ...

  3. 题解-TJOI2015 弦论

    TJOI2015 弦论 字符串 \(s\) 和 \(t\) 和 \(k\).如果 \(t=0\),不同位置的相同子串算 \(1\) 个:如果 \(t=1\),不同位置的相同子串算多个.求 \(k\) ...

  4. 【BZOJ3998】[TJOI2015]弦论 后缀自动机

    [BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...

  5. bzoj3998: [TJOI2015]弦论(SAM+dfs)

    3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...

  6. BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2152  Solved: 716[Submit][Status] ...

  7. Luogu P3975 [TJOI2015]弦论

    题目链接 \(Click\) \(Here\) 题目大意: 重复子串不算的第\(k\)大子串 重复子串计入的第\(k\)大子串 写法:后缀自动机. 和\(OI\) \(Wiki\)上介绍的写法不太一样 ...

  8. 洛谷 P3975 [TJOI2015]弦论 解题报告

    P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...

  9. 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2627  Solved: 881 Description 对于一 ...

  10. BZOJ_3998_[TJOI2015]弦论_后缀自动机

    BZOJ_3998_[TJOI2015]弦论_后缀自动机 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行 ...

随机推荐

  1. qiankun 的 JS 沙箱隔离机制

    为什么需要JS沙箱 想象一下 当一个应用(比如应用 A)加载时,可能会对 window 对象的属性进行修改或添加.如果不加控制,这些修改会影响到之后加载的其他应用(比如应用 B),就会导致属性读写冲突 ...

  2. Flutter showModalBottomSheet改变高度

    showModalBottomSheet改变高度 将isScrollControlled设置为true,此时弹窗会全屏展示,再返回一个带高度的SizedBox,就可以指定弹窗的高度了 showModa ...

  3. logback 中打印自定义参数 (ip 服务名)

    打印 application.properties 配置文件中的参数 首先需要引入文件 <property resource="application.properties" ...

  4. Consul-template, Nginx 实现Thrift Consul负载均衡

    整体架构 我们先看下整个框架的架构是什么样子的,这里我们有三个服务提供者和三个服务调用者,它们通过 Consul 和 Nginx,以及 Consul-template 来实现负载均衡. 说明 本例子是 ...

  5. Kaggle API使用范例

    kaggle.com/docs/api

  6. python SQLAlchemy ORM——从零开始学习 01 安装库

    01基础库 1-1安装 依赖库:sqlalchemy pip install sqlalchemy #直接安装即可 1-2导入使用 这里讲解思路[个人的理解],具体写其实就是这个框架: 导入必要的接口 ...

  7. Mac_工具使用汇总

      Mac安装低版本的Xcode后会出现各种问题,现汇总如下: 1. python3: error: unable to find utility "python3", not a ...

  8. (六).NET6.0通用读取配置文件功能

    1.新增Microsoft.Extensions.Configuration包 在启动项目下,设置appsettings.json属性为始终复制 2.新建一个文件夹Common,用于存放工具类项目.并 ...

  9. springboot整合security实现权限控制

    1.建表,五张表,如下:1.1.用户表CREATE TABLE `t_sys_user` ( `user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ...

  10. MySQL如果数据存在则更新,不存在则插入

    如果数据存在则更新,不存在则插入,MySQL有duplicate.replace into.replace三种方式如何更新数据? insert ignore into 又是如何插入数据的呢? 准备表和 ...