SPOJ 7258 Lexicographical Substring Search [后缀自动机 DP]
题意:给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个。
第一道自己做的1A的SAM啦啦啦
很简单,建SAM后跑kth就行了
也需要按val基数排序倒着推出来d[s]状态s的后继子串个数
跑kth的时候判断d[v]>=k的时候就跑到v,并且k应该是--哦,因为一个子串过去了
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <map>
- using namespace std;
- const int N=2e5+;
- inline int read(){
- char c=getchar();int x=,f=;
- while(c<''||c>''){if(c=='-')f=-; c=getchar();}
- while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
- return x*f;
- }
- int n,Q,k;
- char s[N];
- struct State{
- int ch[],par,val;
- }t[N];
- int sz,root,last;
- inline int nw(int _){t[++sz].val=_;return sz;}
- inline void iniSAM(){sz=;root=last=nw();}
- void extend(int c){
- int p=last,np=nw(t[p].val+);
- for(;p&&!t[p].ch[c];p=t[p].par) t[p].ch[c]=np;
- if(!p) t[np].par=root;
- else{
- int q=t[p].ch[c];
- if(t[q].val==t[p].val+) t[np].par=q;
- else{
- int nq=nw(t[p].val+);
- memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch));
- t[nq].par=t[q].par;
- t[q].par=t[np].par=nq;
- for(;p&&t[p].ch[c]==q;p=t[p].par) t[p].ch[c]=nq;
- }
- }
- last=np;
- }
- int c[N],a[N],d[N];
- void RadixSort(){
- for(int i=;i<=sz;i++) c[t[i].val]++;
- for(int i=;i<=n;i++) c[i]+=c[i-];
- for(int i=;i<=sz;i++) a[c[t[i].val]--]=i;
- }
- void dp(){
- for(int i=sz-;i>=;i--){
- int u=a[i];
- d[u]=;
- for(int j=;j<;j++) d[u]+=d[t[u].ch[j]];//,printf("ch %d %d\n",t[u].ch[j],d[t[u].ch[j]]);
- //printf("state %d %d %d %d %d\n",i,u,t[u].val,d[u],sd[u]);
- }
- }
- void kth(int k){
- int u=root;
- while(k>){//printf("hi %d %d\n",k,u);
- for(int i=;i<;i++) if(t[u].ch[i]){
- int v=t[u].ch[i];//printf("v %d %d %d\n",v,d[v],sd[v]);
- if(d[v]>=k) {putchar('a'+i);k--;u=v;break;}
- else k-=d[v];
- }
- }
- putchar('\n');
- }
- int main(){
- freopen("in","r",stdin);
- scanf("%s",s+);
- n=strlen(s+);
- iniSAM();
- for(int i=;i<=n;i++) extend(s[i]-'a');
- RadixSort();
- dp();
- Q=read();
- while(Q--){
- k=read();
- kth(k);
- }
- }
SPOJ 7258 Lexicographical Substring Search [后缀自动机 DP]的更多相关文章
- spoj 7258 Lexicographical Substring Search (后缀自动机)
spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...
- SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组
SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...
- SP7258 SUBLEX - Lexicographical Substring Search - 后缀自动机,dp
给定一个字符串,求本质不同排名第k小的子串 Solution 后缀自动机上每条路径对应一个本质不同的子串 按照 TRANS 图的拓扑序,DP 计算出每个点发出多少条路径 (注意区别 TRANS 图的拓 ...
- ●SPOJ 7258 Lexicographical Substring Search
题链: http://www.spoj.com/problems/SUBLEX/题解: 后缀自动机. 首先,因为相同的子串都被存在了自动机的同一个状态里面,所以这就很自然的避免了重复子串的问题. 然后 ...
- SPOJ 7258 Lexicographical Substring Search(后缀自动机)
[题目链接] http://www.spoj.com/problems/SUBLEX/ [题目大意] 给出一个字符串,求其字典序排名第k的子串 [题解] 求出sam上每个节点被经过的次数,然后采用权值 ...
- SPOJ Lexicographical Substring Search 后缀自动机
给你一个字符串,然后询问它第k小的factor,坑的地方在于spoj实在是太慢了,要加各种常数优化,字符集如果不压缩一下必t.. #pragma warning(disable:4996) #incl ...
- SPOJ SUBLEX Lexicographical Substring Search - 后缀数组
题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...
- SPOJ 7258 Lexicographical Substring Search
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...
- SP7258 SUBLEX - Lexicographical Substring Search(后缀自动机)
传送门 解题思路 首先建\(sam\),然后在拓扑序上\(dp\)一下,把每个点的路径数算出来,然后统计答案时就在自动机上\(dfs\)一下,仿照平衡树那样找第\(k\)小. 代码 #include& ...
随机推荐
- IntelliJ IDEA 配置 smartGit
教你如何在IntelliJ IDEA中配置smartGit? 一.第一种方式: 1.在启动IDEA工具时,点击下拉按钮"Check out from Version Control" ...
- [国嵌攻略][108][Linux内核链表]
链表简介 链表是一种常见的数据结构,它通过指针将一系列数据节点连接成一条数据链.相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入 ...
- sublimeserver启动本地服务器(sublime text)
今天又get到了一个新知识点,就是在sublime text上也可以模拟一个本地服务器的环境,前提是要先安装sublimeserver这个插件.这个插件的安装办法有两种. 1.我们可以直接在subli ...
- HDU 1979 Red and Black
题目: There is a rectangular room, covered with square tiles. Each tile is colored either red or black ...
- node学习笔记1——require参数查找策略
require参数类型 http.fs.path等,原生模块 ./mod或../mod,相对路径的文件模块 /pathtomodule/mod,绝对路径的文件模块 mod,非原生模块的文件模块 mo ...
- 从零开始学习前端JAVASCRIPT — 4、JavaScript基础Math和Date对象的介绍
Math对象的介绍 1:Math对象 Math 对象用于执行数学任务.并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math().您无需创建它,通过把 Math 作为对象使用就 ...
- 邓_thinkphp口试
描述php框架开发 通过提供一个开发Web程序的基本架构,PHP开发框架把PHPWeb程序开发摆到了流水线上.换句话说,PHP开发框架有助于促进快速软件开发(RAD),这节约了你的时间,有助于创建更为 ...
- YAML书写规范
1. 认识 YAML YAML是一个类似 XML.JSON 的标记性语言.YAML 强调以数据为中心,并不是以标识语言为重点.因而 YAML 本身的定义比较简单,号称"一种人性化的数据格式语 ...
- 解决svn--Unable to connect to a repository at URL ‘https://xxxxxx’ 问题
在checkout项目时,出现如下错误: Error Unable to connect to a repository at URL 'https://XXXX' Error Access to ...
- windows的三种内存管理方法
Windows的内存管理方法 windows提供了3种方法来进行内存管理: l 虚拟内存,最适合用来管理大型对象或者结构数组 l 内存映射文件,最适合用来管理大型数据流 ...