K小子串 / 弦论

题目链接:ybt金牌导航2-3-3 / luogu P3975

题目大意

给你一个字符串,要你求字典序第 k 小的子串。
(相同的子串可能算一个,也可能算多个,数据以读入 0/1 来判断)

思路

考虑用 SAM 来做。

如果相同的子串算一个,那其实就是这一道题,直接看这道题的题解就可以了。
——>链接<——

接着我们来看如果相同的子串算多个怎么做。
那很明显就是要求出这个子串有多少个。
那我们可以通过 DP 来求。考虑到 faifa_ifai​ 的性质(后缀),我们可以用它的逆拓扑序顺序枚举点 iii,然后 faifa_ifai​ 的个数加上它的个数,设求出的是 sizeisize_isizei​。
(其实相同的子串算一个的话就其实就把 sizeisize_isizei​ 都等于 111)

然后由于你有一些点是复制得到的,那那些点的 sizesizesize 初始化的时候就是 000,不是复制的初始化就是 111,不然你会一个加进去的字符可能会因此计算两次。

接着就跟之前一样 DP,求出 iii 出发每个子串的这个值的和。

然后就跟相同算一个时的做法一样了,直接用来比较的值变了。
而且你输出这个字符去找下一个的之后,原来我们只用减一,是因为相同的只算一个,但现在算多个了,那减去的就是 sizeisize_isizei​。

然后就好了。

代码

#include<cstdio>
#include<cstring>
#define ll long longusing namespace std;struct node {int len, fa, size;ll f, size_s;int son[31];node() {memset(son, 0, sizeof(son));len = fa = size = 0;f = -1ll;size_s = 0ll;}
}d[1000001];
int n, tot, lst, T, k;
int tong[1000001], xx[1000001];
char s[500001];void SAM_build(int now) {int p = lst;int np = ++tot;d[np].len = d[p].len + 1;lst = np;d[np].size = 1;//新增点的大小是1for (; p && !d[p].son[now]; p = d[p].fa)d[p].son[now] = np;if (!p) d[np].fa = 1;else {int q = d[p].son[now];if (d[q].len == d[p].len + 1) d[np].fa = q;else {int nq = ++tot;d[nq] = d[q];d[nq].size = 0;//复制点的大小是0d[nq].len = d[p].len + 1;d[q].fa = nq;d[np].fa = nq;for (; p && d[p].son[now] == q; p = d[p].fa) {d[p].son[now] = nq;}}}
}void dfs(int now) {if (d[now].f != -1) return ;d[now].f = 0;for (int i = 0; i < 26; i++)if (d[now].son[i]) {dfs(d[now].son[i]);d[now].f += d[d[now].son[i]].f;}d[now].f++;
}void work(int now, int num) {while (num) {for (int i = 0; i < 26; i++)if (d[now].son[i]) {if (d[d[now].son[i]].f >= num) {putchar(i + 'a');now = d[now].son[i];num--;break;}else num -= d[d[now].son[i]].f;}}
}void get_size() {for (int i = 0; i <= n; i++)//奇数排序按len从大到小排tong[i] = 0;for (int i = 1; i <= tot; i++)tong[d[i].len]++;for (int i = 1; i <= n; i++)tong[i] += tong[i - 1];for (int i = 1; i <= tot; i++)xx[tong[d[i].len]--] = i;for (int i = tot; i >= 1; i--) {d[d[xx[i]].fa].size += d[xx[i]].size;//转移得到 1 到 xx[i] 形成的子串的出现次数}d[1].size = 0;//DP 求出从前缀是 1 到 xx[i] 形成的串的有多少个子串for (int i = tot; i >= 1; i--) {d[xx[i]].size_s = d[xx[i]].size;for (int j = 0; j < 26; j++)if (d[xx[i]].son[j])d[xx[i]].size_s += d[d[xx[i]].son[j]].size_s;}
}void work_s(int now, int num) {num -= d[1].size;while (num > 0) {for (int i = 0; i < 26; i++)if (d[now].son[i]) {if (d[d[now].son[i]].size_s >= num) {putchar(i + 'a');now = d[now].son[i];num -= d[now].size;//记得这里是减去它这个子串,之前只算一个只用减一,现在要减的就是这个子串的个数了break;}else num -= d[d[now].son[i]].size_s;}}
}int main() {scanf("%s", s + 1);n = strlen(s + 1);scanf("%d %d", &T, &k);tot = lst = 1;for (int i = 1; i <= n; i++)SAM_build(s[i] - 'a');dfs(1);if (!T) {if (k > d[1].f) {printf("-1");return 0;}work(1, k);}else {get_size();if (k > d[1].size_s) {printf("-1");return 0;}work_s(1, k);}return 0;
}

【ybt金牌导航2-3-3】【luogu P3975】K小子串 / 弦论相关推荐

  1. 【ybt金牌导航8-3-3】【luogu P4593】分数计算 / 教科书般的亵渎(数学)(拉格朗日插值)

    分数计算 / 教科书般的亵渎 题目链接:ybt金牌导航8-3-3 / luogu P4593 题目大意 有一些怪,血量从 1~n,其中有 m 个数是没有怪的,给出这些数. 然后你可以每次操作攻击所有怪 ...

  2. 【ybt金牌导航4-7-3】【luogu P3437】三维俄罗斯方块/TET-Tetris 3D

    三维俄罗斯方块/TET-Tetris 3D 题目链接:ybt金牌导航4-7-3 / luogu P3437 题目大意 要你支持区间求最大,并把这个区间的所有点高度改为你求得的最大值加一个值. 最后要你 ...

  3. 【ybt金牌导航3-6-3】【luogu P3007】奶牛议会 / The Continental Cowngress G(两种方法)

    奶牛议会 / The Continental Cowngress G 题目链接:ybt金牌导航3-6-3 / luogu P3007 题目大意 有一些人,每个人对众多决案中的两个决案有表示好或不好. ...

  4. 【ybt金牌导航3-2-1】【luogu P3376】网络最大流【Dinic算法】

    网 络 最 大 流 网络最大流 网络最大流 题目链接:ybt金牌导航3-2-1 / luogu P3376 题目 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入 第一行包含四个正整数 ...

  5. 【luogu P4036】【ybt金牌导航4-5-3】火星人

    火星人 题目链接:luogu P4036 / ybt金牌导航4-5-3 题目大意 给你一个字符串,要你维护三个东西. 修改字符串的一个字符,往字符串的一个地方插入一个字符,询问两个后缀的最长公共前缀. ...

  6. 【启发式合并】梦幻布丁(金牌导航 启发式合并-1/luogu 3201)

    梦幻布丁 金牌导航 启发式合并-1 luogu 3201 题目大意 有若干个布丁,给出它们的颜色,每次将一个颜色的所有布丁变成另一种颜色,然后询问有多少段连续的数 输入样例 4 3 1 2 2 1 2 ...

  7. 【ybt金牌导航8-7-1】数对统计 / 关于莫比乌斯函数的少量内容

    数对统计 题目链接:ybt金牌导航8-7-1 题目大意 给你 n,m,求 gcd(x,y)=1 的数对个数. 1<=x<=n,1<=y<=m 思路 莫比乌斯函数 什么东西 首先 ...

  8. P3975 [TJOI2015]弦论 第K小子串

    题目描述 https://www.luogu.org/problem/P3975 为了提高智商,ZJY开始学习弦论.这一天,她在< String theory>中看到了这样一道问题:对于一 ...

  9. 【DP】【树状数组】方伯伯的玉米田/优美玉米(luogu 3287/金牌导航 数据结构优化DP-5)

    正题 luogu 3287 金牌导航 数据结构优化DP-5 题目大意 有n个玉米,给出高度,你可以选择一个区间,使这个区间的玉米高度+1,你可以进行k次这样的操作,查询你操作完后最长不下降子序列最大值 ...

最新文章

  1. 程序员该有的职业素养
  2. 我知道今天是写总结的日子-所以买了一罐啤酒喝
  3. python界面长什么样子-图形界面
  4. STM32下一次程序后J-link不能识别问题解决
  5. 算法提高课-搜索-DFS之连通性模型-AcWing 1112. 迷宫:dfs和bfs两种解法
  6. iframe cross domain
  7. php页面代码简化,代码求简化
  8. Composite(组合)--对象结构型模式
  9. R学习-- 数组和矩阵
  10. Docker 的4种网络模式
  11. leetcode - 221. 最大正方形
  12. php如何循环输出图片,thinkphp 循环显示图片问题!!!~~~~
  13. sql server 表结构信息查询
  14. excel宏的使用图解教程
  15. VISA/MasterCard/AE/DC/JCB卡号结构
  16. cs透视源码c语言,CS--GO透视自瞄C++源码 CSGO C++源代码 参考学习!!!(CSGO C++ source code) - 下载 - 搜珍网...
  17. 解决用U盘重装Mac系统中电脑无法识别U盘的问题
  18. 问题 F: 是你飘了,还是我拿不动刀了(字符串问题)
  19. 电脑分区合并——灰色解决方法
  20. python对excel筛选提取文本中数字_详解利用python提取pdf文本数字

热门文章

  1. 干货 I 用数据分析进行“无死角”的复盘?
  2. 14、pyspider框架
  3. CS(反恐精英)奥林匹克运动会
  4. 为什么使用kbhit后按下键盘无反应?
  5. 微信小程序动态点赞php,微信小程序小组件基于Canvas实现直播点赞气泡效果
  6. 原材料入库控制的三个问题
  7. 【Unity】Unity 脚下光圈
  8. 给出x.509证书的实例并分析其工作方式
  9. 实验室预约管理系统(Java+SSH+Web+MySQL+ofbiz系统)
  10. ERROR Error loading vue.config.js ERROR Error Command failed git describe --always报错可能的原因