[TJOI2015]弦论(后缀自动机)
题意:
对给定字符串\(s\),求其第\(k\)小子串,重复串被计入以及不被计入这两种情况都需考虑。
思路:
首先构建后缀自动机,之后就考虑在后缀自动机上\(dp\)。
我们知道如果要考虑重复串,那么就会与一个结点的\(endpos\)集合的大小有关,对于一条边\((u,v)\),如果结点\(u\)的\(endpos\)集合大小为\(x\),那么就说明从\(u\)出发到达\(v\),会多出\(x\)种选择。
如果不考虑重复串,直接强制集合大小为\(1\)即可。
之后逆着拓扑序\(dp\)就行,求出从每个结点出发的子串个数。
最后求第\(k\)小的时候,有一些细节需要注意一下,比如从\(u\)到\(v\),\(k\)应该减去\(|endpos(v)|\),因为现在的字符串会有\(|endpos(v)|\)个。
感觉后缀自动机好神奇...好多的性质以及用法...
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
struct node{
int ch[26];
int len, fa;
node(){memset(ch, 0, sizeof(ch)), len = 0;}
}dian[N];
int last = 1, tot = 1;
ll f[N], sum[N];
int n, k, op;
char s[N];
int c[N], a[N];
void add(int c) {
int p = last;
int np = last = ++tot;
dian[np].len = dian[p].len + 1;
f[np] = 1;
for(; p && !dian[p].ch[c]; p = dian[p].fa) dian[p].ch[c] = np;
if(!p) dian[np].fa = 1;
else {
int q = dian[p].ch[c];
if(dian[q].len == dian[p].len + 1) dian[np].fa = q;
else {
int nq = ++tot; dian[nq] = dian[q];
dian[nq].len = dian[p].len + 1;
dian[q].fa = dian[np].fa = nq;
for(; p && dian[p].ch[c] == q; p = dian[p].fa) dian[p].ch[c] = nq;
}
}
}
void dfs(int u) {
if(k <= 0) return;
for(int i = 0; i < 26; i++) {
int v = dian[u].ch[i];
if(k > sum[v]) k -= sum[v];
else {
cout << char(i + 'a');
k -= f[v];
dfs(v);
return;
}
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> s + 1 >> op >> k;
int n = strlen(s + 1);
for(int i = 1; i <= n; i++) add(s[i] - 'a');
for(int i = 1; i <= tot; i++) c[dian[i].len]++;
for(int i = 1; i <= tot; i++) c[i] += c[i - 1];
for(int i = 1; i <= tot; i++) a[c[dian[i].len]--] = i;
for(int i = tot; i; i--) {
if(op) f[dian[a[i]].fa] += f[a[i]];
else f[a[i]] = 1;
}
f[1] = 0;
//长度从大到小,逆着拓扑序
//每个结点的next指针指向的点长度肯定不小于它
for(int i = tot; i >= 1; i--) {
sum[a[i]] = f[a[i]];
for(int j = 0; j < 26; j++) {
int v = dian[a[i]].ch[j];
if(v) sum[a[i]] += sum[v];
}
}
if(sum[1] < k) cout << -1;
else dfs(1);
return 0;
}
[TJOI2015]弦论(后缀自动机)的更多相关文章
- 【BZOJ3998】[TJOI2015]弦论 后缀自动机
[BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- [bzoj3998][TJOI2015]弦论-后缀自动机
Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...
- BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串
http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...
- BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...
- BZOJ 3998 [TJOI2015]弦论 ——后缀自动机
直接构建后缀自动机. 然后. 然后只需要再后缀自动机的go树上类似二分的方法进行查找即可,实际上是“26分”. 然后遇到了处理right集合的问题,然后觉得在go和parent树上上传都是可以的,毕竟 ...
- [TJOI2015]弦论(后缀自动机)
/* 一道在树上乱搞的题目 建立出parent树来, 然后就能搞出每个节点往后能扩展出几个串, 至于位置不同算同一个的话就强制让right集合大小为1即可 然后在树上类比权值线段树找第k大26分统计一 ...
- BZOJ.3998.[TJOI2015]弦论(后缀自动机)
题目链接 \(Description\) 给定字符串S,求其第K小子串.(若T=0,不同位置的相同子串算1个:否则算作多个) \(Solution\) 建SAM,处理出对于每个节点,它和它的所有后继包 ...
- bzoj 3998 [TJOI2015]弦论——后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3998 相同子串算多个的话,先求好 right ,然后求一个 sm 表示走到这个点之后有几种走 ...
随机推荐
- 8.5 NOIP模拟测试13 矩阵游戏+跳房子+优美序列
T1矩阵游戏 数学题.首先这一列这一行先乘还是后乘对最后答案没有影响.a[i][j]表示矩阵中原始的值,h[i]表示i行的累乘,l[i]表示i列的累乘.易得ans=Σa[i][j]*h[i]*l[i] ...
- 【Arch安装】
[Arch安装]不完整,凭记忆补充 1,制作安装介质(请跳转链接:https://www.archlinux.org/download/) 2,从UEFI模式启动后,按照官方WIKI向导操作(http ...
- 我已经看到了,撤回也没用了(PC微信防撤回补丁)
前两天看 GitHub 发现一个有趣的项目,PC微信防撤回补丁,本着研究学习的目的,在看过源码,一顿疯狂操作之后,了解了其原理是基于修改 wechatwin.dll 达到防撤回的. 于是乎,自己动手玩 ...
- redis-安装卸载
1.安装service服务 redis-server --service-install [配置文件位置,如:redis.conf] (--service-name 服务名称) 2.启动service ...
- wifi串口服务器
下面与大家分享上海卓岚无线wifi串口服务器ZLAN7104创建虚拟串口的设置使用心得 一.7104网线连接计算机,用ZLVircom即可搜索并配置 其中,串口设置需要匹配实际所接的串口设备,配置为相 ...
- IDEA整合GIT所有操作
IDEA整合GIT操作 1.1 配置Idea集成Git 1.2 在使用SSH key 创建公钥私钥,上传公钥到github (1).点击开始菜单-->所有程序--->git选择 Git B ...
- 【题解】C2Crni - Crni [COCI2010] [SP7884]
[题解]C2Crni - Crni [COCI2010] [SP7884] 传送门:\(\text{C2Crni - Crni}\) \(\text{[COCI2010]}\) \(\text{[SP ...
- 【03】Jenkins:SonarQube
写在前面的话 SonarQube 这个服务有些人熟悉,有些人陌生.对于我们这样的运维人员,我们需要了解的是,SonarQube 是一个代码质量管理平台,懂得怎么安装配置,这其实就差不多足够了.我们在 ...
- 【03】Saltstack:远程执行
写在前面的话 远程执行可以说是我们使用 Saltstack 最为基础的目的.所以在这里专门作为单独的一篇来详细的聊聊. 远程执行命令 示例命令: salt '*' cmd.run 'w' 命令分析: ...
- 【mybatis】标签条件中判断入参属性值是否包含子字符串
可以直接使用 contains判断 <foreach collection="list" item="item" index="index&qu ...