[TJOI2015] 弦论 题解
所有子串,一眼 \(\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] 弦论 题解的更多相关文章
- 洛谷 P3975 / loj 2102 [TJOI2015] 弦论 题解【后缀自动机】【拓扑排序】
后缀自动机入门. 题目描述 为了提高智商,ZJY 开始学习弦论. 这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为 \(n\) 的字符串,求出它的第 \ ...
- BZOJ3998:[TJOI2015]弦论——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3998 https://www.luogu.org/problemnew/show/P3975 对于 ...
- 题解-TJOI2015 弦论
TJOI2015 弦论 字符串 \(s\) 和 \(t\) 和 \(k\).如果 \(t=0\),不同位置的相同子串算 \(1\) 个:如果 \(t=1\),不同位置的相同子串算多个.求 \(k\) ...
- 【BZOJ3998】[TJOI2015]弦论 后缀自动机
[BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...
- bzoj3998: [TJOI2015]弦论(SAM+dfs)
3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- Luogu P3975 [TJOI2015]弦论
题目链接 \(Click\) \(Here\) 题目大意: 重复子串不算的第\(k\)大子串 重复子串计入的第\(k\)大子串 写法:后缀自动机. 和\(OI\) \(Wiki\)上介绍的写法不太一样 ...
- 洛谷 P3975 [TJOI2015]弦论 解题报告
P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...
- 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2627 Solved: 881 Description 对于一 ...
- BZOJ_3998_[TJOI2015]弦论_后缀自动机
BZOJ_3998_[TJOI2015]弦论_后缀自动机 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行 ...
随机推荐
- 实现不可逆加密文件:探索 GodoOS 的安全机制
在当今数字化时代,数据安全成为了企业和个人关注的重点.为了保护敏感信息不被未授权访问,各种加密技术应运而生.本文将探讨 GodoOS 项目中实现的一种不可逆加密文件的方法,重点介绍其背后的原理和技术细 ...
- C#中使用IMemoryCache实现内存缓存
1 缓存基础知识 缓存是实际工作中非常常用的一种提高性能的方法. 缓存可以减少生成内容所需的工作,从而显著提高应用程序的性能和可伸缩性. 缓存最适用于不经常更改的数据. 通过缓存,可以比从原始数据源返 ...
- 关于Pro addin中,控制dockpane的状态
在Pro SDK中,可以通过dackpane的Hide()方法,对面板进行隐藏. DockPane pane = FrameworkApplication.DockPaneManager.Find(& ...
- Element Plus组件el-select回显异常
前情 公司有经常需要做一些后台管理页面,我们选择了Element Plus,它是基于 Vue 3,面向设计师和开发者的组件库,是Vue框架生态中比较火的UI组件库,组件库丰富易用,组件链接:一个 Vu ...
- iOS - 利用 UIBezierPath 绘制圆弧
iOS - 利用 UIBezierPath 绘制圆弧 API UIBezierPath 绘制圆弧主要利用以下方法: open func addArc(withCenter center: CGPoin ...
- KTL 用C++14写公式的K线工具 - 0.9.3版
K,K线,Candle蜡烛图. T,技术分析,工具平台 L,公式Language语言使用c++14,Lite小巧简易. 项目仓库:https://github.com/bbqz007/KTL 国内仓库 ...
- 【分享】记一次项目迁移(docker java | docker python)
项目:前端Vue3,后端Python+Java,数据库Redis+MySQL 原先部署在centos7里面的,使用的宝塔面板部署的,还算方便. 但是服务器要到期了,要将项目迁移到另外一台服务器. 另外 ...
- 【转载】茅台巽风app地图详解,做任务不迷路,纯手绘
茅台发布了新的app"巽风" 根据"巽值"的排名,发放20000个虎年茅台的资格,还是可以玩一玩的 哪些途径获取"巽值" 1.做任务,和游戏 ...
- docker.sock: connect: permission denied 解决
问题描述xjun@DESKTOP-L2R4GKN:~$ docker run -it hello-worlddocker: Got permission denied while trying to ...
- Ubuntu下安装make
方法一:(自动安装) 1.进入root权限:su root 2.更新安装列表:apt-get update 3.安装make:apt-get install ubuntu-make 方法二:(手动安装 ...