BZOJ3998: [TJOI2015]弦论(后缀自动机,Parent树)
Description
对于一个给定长度为N的字符串,求它的第K小子串是什么。
Input
第一行是一个仅由小写英文字母构成的字符串S
Output
输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1
Sample Input
0 3
Sample Output
解题思路:
在后缀自动机Parent树上的每个节点所代表的串都是以祖先节点为后缀的逆序子串。
利用这一性质我们可以很方便地求解一个子串出现多少次的问题(其子树内实点数)
那么这道题是求解排名的问题。
一个后缀自动机可以识别一个串所有后缀。
若按前缀查询,就是所有字串,字串出现次数和就是其母串次数和的累加。
当 t=0 时,认为其实点只有自己记录。
而 t=1时,认为其子节点被记录。
累加其sum值作为以此值为前缀的串个数。
最后相减逼近答案输出即可。
代码:
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- typedef long long lnt;
- struct sant{
- int tranc[];
- int len;
- int pre;
- }s[];
- struct pnt{
- lnt sum;
- lnt size;
- }p[];
- int siz;
- int fin;
- int n,t;
- lnt k;
- char tmp[];
- int has[];
- int topo[];
- void Insert(int c)
- {
- int nwp,nwq,lsp,lsq;
- nwp=++siz;
- s[nwp].len=s[fin].len+;
- p[nwp].size=;
- for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
- s[lsp].tranc[c]=nwp;
- if(!s[lsp].tranc[c])
- s[nwp].pre=;
- else{
- lsq=s[lsp].tranc[c];
- if(s[lsq].len==s[lsp].len+)
- s[nwp].pre=lsq;
- else{
- nwq=++siz;
- s[nwq]=s[lsq];
- s[nwq].len=s[lsp].len+;
- s[nwp].pre=s[lsq].pre=nwq;
- while(s[lsp].tranc[c]==lsq)
- {
- s[lsp].tranc[c]=nwq;
- lsp=s[lsp].pre;
- }
- }
- }
- fin=nwp;
- return ;
- }
- int main()
- {
- fin=siz=;
- scanf("%s",tmp+);
- scanf("%d%lld",&t,&k);
- n=strlen(tmp+);
- for(int i=;i<=n;i++)
- Insert(tmp[i]-'a');
- for(int i=;i<=siz;i++)
- has[s[i].len]++;
- for(int i=;i<=siz;i++)
- has[i]+=has[i-];
- for(int i=;i<=siz;i++)
- topo[has[s[i].len]--]=i;
- for(int i=siz;i;i--)
- if(t)
- p[s[topo[i]].pre].size+=p[topo[i]].size;
- else
- p[topo[i]].size=;
- p[].size=;
- for(int i=siz;i;i--)
- {
- int h=topo[i];
- p[h].sum=p[h].size;
- for(int c=;c<;c++)
- if(s[h].tranc[c])
- p[h].sum+=p[s[h].tranc[c]].sum;
- }
- if(k>p[].sum)
- {
- puts("-1");
- return ;
- }
- int root=;
- while(k>)
- {
- for(int c=;c<;c++)
- {
- int l=s[root].tranc[c];
- if(!l)continue;
- if(k>p[l].sum)
- k-=p[l].sum;
- else{
- putchar('a'+c);
- root=s[root].tranc[c];
- k-=p[root].size;
- break;
- }
- }
- }
- return ;
- }
BZOJ3998: [TJOI2015]弦论(后缀自动机,Parent树)的更多相关文章
- [bzoj3998][TJOI2015]弦论-后缀自动机
Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...
- 【BZOJ3998】[TJOI2015]弦论 后缀自动机
[BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...
- 【BZOJ-3998】弦论 后缀自动机
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2018 Solved: 662[Submit][Status] ...
- [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增
题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...
- BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...
- BZOJ 3998 [TJOI2015]弦论 ——后缀自动机
直接构建后缀自动机. 然后. 然后只需要再后缀自动机的go树上类似二分的方法进行查找即可,实际上是“26分”. 然后遇到了处理right集合的问题,然后觉得在go和parent树上上传都是可以的,毕竟 ...
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- [TJOI2015]弦论(后缀自动机)
/* 一道在树上乱搞的题目 建立出parent树来, 然后就能搞出每个节点往后能扩展出几个串, 至于位置不同算同一个的话就强制让right集合大小为1即可 然后在树上类比权值线段树找第k大26分统计一 ...
- BZOJ.3998.[TJOI2015]弦论(后缀自动机)
题目链接 \(Description\) 给定字符串S,求其第K小子串.(若T=0,不同位置的相同子串算1个:否则算作多个) \(Solution\) 建SAM,处理出对于每个节点,它和它的所有后继包 ...
随机推荐
- 30.angularJS第一个实例
转自:https://www.cnblogs.com/best/tag/Angular/ AngularJS 通过 ng-directives 扩展了 HTML. ng-app 指令定义一个 Angu ...
- BZOJ 1503 treap
思路: treap (算是基本操作吧-..) 加减的操作数很少 就暴力好啦 每回判断一下最小的数是不是比M小 如果是 就删,继续判断 搞定. //By SiriusRen #include <c ...
- cf 864 F. Cities Excursions
F. Cities Excursions There are n cities in Berland. Some pairs of them are connected with m directed ...
- CSS3新的UI方案
文本新增样式 一.opacity:指定了一个元素的透明度 0~1 二.新增颜色模式rgba:很好的解决了背景透明,字体颜色不透明的需求. 三.文字阴影:text-shadow用来为文字添加阴影,而且可 ...
- CSS2.1(布局)
浏览器内核 Firefox : geckoIE: tirdentSafari: webkitChrome: 一开始使用webkit 后来基于webkit开发了Blinkopera: 一开始使用pres ...
- BZOJ2668: [cqoi2012]交换棋子(费用流)
Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列的格子只能参与mi,j次交换. Input 第一行 ...
- react-native-swiper苹果正常显示,Android不显示
在使用react-native-swiper时,最好不要放到(FlatList , SectionList,ListView,ScrollView 等)组件中,否则Android 可能不会正常显示图片 ...
- android 4.4最新官方源代码下载
国内网络,日夜不休花了一个多月才下载成功android标准源代码,有些开发同人须要.已上传到网盘,分享给大家 微云地址: http://url.cn/PkkSzC 百度云盘地址(更新) http:// ...
- 使用Spring Mvc 转发 带着模板 父页面 之解决方法 decorators.xml
周末了,周一布置的任务还没完毕,卡在了页面跳转上,接手了一个半截的项目要进行开发,之前没有人给培训.全靠自己爬代码,所以进度比較慢.并且加上之前没实用过 Spring Mvc 开发项目.所以有点吃力, ...
- hdu 5312 Sequence(数学推导——三角形数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5312 Sequence Time Limit: 2000/2000 MS (Java/Others) ...