[BZOJ]3998 [TJOI2015] 弦论 后缀自动机
来源:互联网 发布:软件机器码修改 编辑:程序博客网 时间:2024/05/16 07:57
3998: [TJOI2015]弦论
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 3292 Solved: 1133
[Submit][Status][Discuss]
Description
对于一个给定长度为N的字符串,求它的第K小子串是什么。
Input
第一行是一个仅由小写英文字母构成的字符串S
第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。K的意义如题所述。
Output
输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1
Sample Input
aabc
0 3
0 3
Sample Output
aab
HINT
N<=5*10^5
T<2
K<=10^9
Source
HOME Back
以前wjj给我讲过但那是暑假的事了... 现在几乎都忘光了... 不过重拾起来还是非常快? 虽然一开始看毛子论文的各种专业术语乱飚一脸懵逼, 不过努力回想wjj讲过的内容在纸上推推还是推出来了... 明白了以后看了下clj神犇的论文发现这玩意性质还非常多? 感觉比今早上学的回文自动机要高级多了... 看来还是得多学习一个... 争取深入理解后缀自动机, 把性质都记录下来推一推多做点题.
这道题很简单, 两种情况分类讨论逆拓扑序倒推预处理, 然后询问第k大可以说是...26分?
#include<stdio.h>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1000005;char ss[maxn];int n, k, T, cnt = 1, last = 1;int ws[maxn], sa[maxn], c[maxn][26], dep[maxn], val[maxn], sum[maxn], par[maxn];struct sam{inline void build(int x) {int p = last, np = last = ++ cnt;dep[np] = dep[p] + 1; val[np] = 1;while (p && !c[p][x]) c[p][x] = np, p = par[p];if (!p) par[np] = 1;else {int who = c[p][x];if (dep[who] == dep[p] + 1) par[np] = who;else {int anwho = ++ cnt;dep[anwho] = dep[p] + 1;memcpy(c[anwho], c[who], sizeof(c[who]));par[anwho] = par[who]; par[np] = par[who] = anwho; while (c[p][x] == who) c[p][x] = anwho, p = par[p]; }}}inline void init() {for (int i = 1; i <= cnt; ++ i) ws[dep[i]] ++; for (int i = 1; i <= n; ++ i) ws[i] += ws[i - 1];for (int i = cnt; i; -- i) sa[ws[dep[i]]--] = i;for (int i = cnt; i; -- i) {int t = sa[i];if (T & 1) val[par[t]] += val[t];else val[t] = 1;}val[1] = 0;for (int i = cnt; i; -- i) {int t = sa[i]; sum[t] = val[t];for (int ch = 0; ch < 26; ++ ch) sum[t] += sum[c[t][ch]];}}void calc(int x,int k) { while(true) {if (k <= val[x]) return;k -= val[x];for (int i = 0; i < 26; ++ i) { int t = c[x][i]; if (t) { if (k <= sum[t]) { putchar(i + 'a'); x = t; break;}k -= sum[t];}}} }}sam; int main() {scanf("%s", ss + 1); n = strlen(ss + 1);scanf("%d%d", &T, &k);for (int i = 1; i <= n; ++ i) sam.build(ss[i] - 'a');sam.init();if (k > sum[1]) puts("-1");else sam.calc(1,k);return 0;}
阅读全文
0 0
- BZOJ 3998 TJOI2015 弦论 后缀自动机
- BZOJ 3998 TJOI2015 弦论 后缀自动机
- 【后缀自动机】 BZOJ 3998: [TJOI2015]弦论
- bzoj 3998: [TJOI2015]弦论 (后缀自动机)
- bzoj 3998: [TJOI2015]弦论 后缀自动机
- [BZOJ]3998 [TJOI2015] 弦论 后缀自动机
- bzoj 3998 [TJOI2015]弦论 后缀数组||后缀自动机
- BZOJ 3998 [TJOI2015]弦论【后缀自动机(总结+安利
- 3998: [TJOI2015]弦论 后缀自动机
- [K大子串 后缀自动机 模板题] BZOJ 3998 [TJOI2015]弦论
- [BZOJ2555] [TJOI2015]弦论 && 后缀自动机
- 【BZOJ3998】【TJOI2015】弦论 后缀自动机
- [BZOJ3998]TJOI2015弦论|后缀自动机
- 【bzoj3998】[TJOI2015]弦论 后缀自动机
- 【BZOJ3998】【TJOI2015】 弦论 后缀自动机
- [BZOJ3998] [TJOI2015] 弦论 - 后缀自动机
- 【bzoj3998】[TJOI2015]弦论 后缀自动机
- [BZOJ3998][TJOI2015]弦论 后缀自动机
- 协同过滤的简介
- java过滤字符串中的空格、回车、换行符、制表符等
- leetcode题解-142. Linked List Cycle II
- AliExpress:在检索式问答系统中应用迁移学习 | PaperDaily #24
- 新生赛1008
- [BZOJ]3998 [TJOI2015] 弦论 后缀自动机
- 配置Hanlp
- PHP-PCRE正则表达式
- 中国计算机学会YOCSEF TDS《专题探索班》,新一代人工智能的基础与前瞻
- 欢迎使用CSDN-markdown编辑器
- Vue基础(计算属性和观察者)
- IO流中字节流,高效字节流
- js中const,var,let的区别
- 宏与宏函数