[题目链接 \(Click\) \(Here\)](P3975 [TJOI2015]弦论)

题目大意:

  • 重复子串不算的第\(k\)大子串

  • 重复子串计入的第\(k\)大子串

写法:后缀自动机。

和\(OI\) \(Wiki\)上介绍的写法不太一样,因为要同时解决两个问题。

把字符串每个前缀所在等价类的\(siz\)记为\(1\),然后在\(parent\) \(tree\)上跑一次统计,就可以求出来每一个等价类在串中出现的次数。这里采用类似后缀排序的方法,对字符串按\(len\)为关键字进行排序。至于经过每个点的路径数\(sum\),可以在\(Trie\)边上对后面节点的\(sum\)(=每一个等价类在串中出现次数)求和得到(初始值等于\(siz\),因为每个点还有不选的情况)。

不要忘了把\(siz[1]\)和\(sum[1]\)清空!

#include <bits/stdc++.h>
using namespace std; const int N = 1100010; char s[N];
int las = 1, node = 1;
int fa[N], len[N], siz[N], ch[N][26]; void extend (int c) {
register int p, q, x, y;
p = las, q = ++node; las = q;
len[q] = len[p] + 1; siz[q] = 1;
while (p != 0 && ch[p][c] == 0) {
ch[p][c] = q;
p = fa[p];
}
if (p == 0) {
fa[q] = 1;
} else {
x = ch[p][c];
if (len[x] == len[p] + 1) {
fa[q] = x;
} else {
y = ++node;
fa[y] = fa[x];
fa[x] = fa[q] = y;
len[y] = len[p] + 1;
memcpy (ch[y], ch[x], sizeof (ch[x]));
while (p != 0 && ch[p][c] == x) {
ch[p][c] = y;
p = fa[p];
}
}
}
} int t, k, nd[N], bin[N]; long long sum[N]; void output (int u) {
if (k <= siz[u]) return;
k -= siz[u];
register int i;
for (i = 0; i < 26; ++i) {
if (ch[u][i]) {
if (k > sum[ch[u][i]]) {
k -= sum[ch[u][i]];
} else {
printf ("%c", i + 'a');
output (ch[u][i]);
return;
}
}
}
} int main () {
scanf ("%s %d %d", s, &t, &k);
register int i, j, n;
n = strlen (s);
for (i = 0; i < n; ++i) extend (s[i] - 'a');
for (i = 1; i <= node; ++i) bin[len[i]]++;
for (i = 1; i <= node; ++i) bin[i] += bin[i - 1];
for (i = 1; i <= node; ++i) nd[bin[len[i]]--] = i;
for (i = node; i >= 1; --i) siz[fa[nd[i]]] += siz[nd[i]];
for (i = 1; i <= node; ++i) t == 0 ? (sum[i] = siz[i] = 1) : (sum[i] = siz[i]);
siz[1] = sum[1] = 0;
for (i = node; i >= 1; --i) {
for (j = 0; j < 26; ++j) {
if (ch[nd[i]][j]) {
sum[nd[i]] += sum[ch[nd[i]][j]];
}
}
}
if (sum[1] < k) {
puts ("-1");
} else {
output (1);
}
}

\(p.s\)关于后缀数组求第一问的方法:

枚举每一个后缀,第i个后缀对答案的贡献为\(len−sa[i]+1−height[i]\)。

Luogu P3975 [TJOI2015]弦论的更多相关文章

  1. luogu P3975 [TJOI2015]弦论 SAM

    luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...

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

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

  3. P3975 [TJOI2015]弦论

    思路 一眼SAM板子,结果敲了一中午... 我还是太弱了 题目要求求第k小的子串 我们可以把t=0当成t=1的特殊情况,(所有不同位置的相同子串算作一个就是相当于把所有子串的出现位置个数(endpos ...

  4. [洛谷P3975][TJOI2015]弦论

    题目大意:求一个字符串的第$k$大字串,$t$表示长得一样位置不同的字串是否算多个 题解:$SAM$,先求出每个位置可以到达多少个字串($Right$数组),然后在转移图上$DP$,若$t=1$,初始 ...

  5. 并不对劲的bzoj3998:loj2102:p3975:[TJOI2015]弦论

    题目大意 对于一个给定的长度为n(\(n\leq5*10^5\))的字符串, 分别求出不同位置的相同子串算作一个.不同位置的相同子串算作多个时,它的第k(\(k\leq10^9\))小子串是什么 题解 ...

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

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

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

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

  8. [Luogu 3973] TJOI2015 线性代数

    [Luogu 3973] TJOI2015 线性代数 这竟然是一道最小割模型. 据说是最大权闭合子图. 先把矩阵式子推出来. 然后,套路建模就好. #include <algorithm> ...

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

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

随机推荐

  1. Js 中一系列宽度和高度的学习

    在学习元素一系列宽度和高度之前,我们先来看一个平时开发中几乎不会遇到的问题,那就是html文档声明<!DOCTYPE html> 确实会对元素的宽高产生影响.几乎不会遇到,是因为我们在写h ...

  2. Express学习(1) ------Express 入门

    Express 是node 第三方框架,大家都知道,框架的意义就在于能大大简化程序地开发.那么我们就看一下Express是怎么简化node程序开发的. 1,用Express写一个hello world ...

  3. python变量与基础数据类型

    一.什么是变量 变量是什么?  变量:把程序运行的中间结果临时的存在内存里,以便后续的代码调用.在python中一切都是变量. 1.python变量命名的要求 1,必须有数字,字母,下划线任意组合. ...

  4. Python介绍及环境配置

    Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有 ...

  5. Qt setStyleSheet

    Qt中设置按钮或QWidget的外观是,可以使用QT Style Sheets来进行设置,非常方便.可以用setStyleSheet("font: bold; font-size:20px; ...

  6. BZOJ1412[ZJOI2009]狼和羊的故事——最小割

    题目描述 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈 ...

  7. Vue——显示微信用户名称中enjoin表情

    后端做了处理转为了Unicode编码存入数据库,但是取出来没做处理,所以前端就做下简单的处理 转换代码: function decodeUnicode(str) { str = str.replace ...

  8. Codeforces 719A 月亮

    参考自:https://www.cnblogs.com/ECJTUACM-873284962/p/6395221.html A. Vitya in the Countryside time limit ...

  9. bzoj2212[Poi2011]Tree Rotations [线段树合并]

    题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...

  10. 「POJ3696」The Luckiest number【数论,欧拉函数】

    # 题解 一道数论欧拉函数和欧拉定理的入门好题. 虽然我提交的时候POJ炸掉了,但是在hdu里面A掉了,应该是一样的吧. 首先我们需要求的这个数一定可以表示成\(\frac{(10^x-1)}{9}\ ...