题链:

http://www.spoj.com/problems/SUBLEX/
题解:

后缀自动机。
首先,因为相同的子串都被存在了自动机的同一个状态里面,所以这就很自然的避免了重复子串的问题。
然后考虑自动机里面的转移trans,发现其构成了一个DAG,且从一个状态出发,DFS下去就可以得到所有的不重复的串;
所以我们按照拓扑序对状态排序,然后DP计算出从每个状态出发可以到达多少个子串。
转移方程:$dp[p]=\sum_{trans(p,*)=q,q!=0}dp[q]+1$
然后对于每个输入的k,在自动机里面配合dp数组去dfs就好。

代码:

#include<bits/stdc++.h>
#define MAXN 90005
#define ll long long
using namespace std;
ll cnt[MAXN*3];
struct SAM{
int size,last;
int maxs[MAXN*3],trans[MAXN*3][26],parent[MAXN*3];
int Newnode(int a,int b){
++size; maxs[size]=a;
memcpy(trans[size],trans[b],sizeof(trans[b]));
return size;
}
void Extend(int x){
static int p,np,q,nq;
p=last; last=np=Newnode(maxs[p]+1,0);
for(;p&&!trans[p][x];p=parent[p]) trans[p][x]=np;
if(!p) parent[np]=1;
else{
q=trans[p][x];
if(maxs[p]+1!=maxs[q]){
nq=Newnode(maxs[p]+1,q);
parent[nq]=parent[q];
parent[q]=parent[np]=nq;
for(;p&&trans[p][x]==q;p=parent[p]) trans[p][x]=nq;
}
else parent[np]=q;
}
}
void Build(char *S){
memset(trans[0],0,sizeof(trans[0]));
size=0; last=Newnode(0,0);
for(int i=0;S[i];i++) Extend(S[i]-'a');
}
}SUF;
void DP(){
static int in[MAXN*3],A[MAXN*3],ant,q;
queue<int>Q;
for(int p=1;p<=SUF.size;p++)
for(int c=0;c<26;c++){
q=SUF.trans[p][c]; if(!q) continue;
in[q]++;
}
Q.push(1);
while(!Q.empty()){
int p=Q.front(); Q.pop(); A[++ant]=p;
for(int c=0;c<26;c++){
q=SUF.trans[p][c]; if(!q) continue;
in[q]--; if(!in[q]) Q.push(q);
}
}
for(int i=ant,p;i;i--){
p=A[i]; cnt[p]=(p==1?0:1);
for(int c=0;c<26;c++){
q=SUF.trans[p][c]; if(!q) continue;
cnt[p]+=cnt[q];
}
}
// printf("%lld\n",cnt[1]);
}
void dfs(int p,int k,char from){
static int i,q;
static char ans[MAXN];
if(p==1) i=0; else k--,ans[i++]=from;
if(!k) return (void)(ans[i]=0,puts(ans));
for(int c=0;c<26;c++){
q=SUF.trans[p][c]; if(!q) continue;
if(k<=cnt[q]){dfs(q,k,'a'+c); break;}
k-=cnt[q];
}
}
int main(){
static char S[MAXN];
scanf("%s",S);
SUF.Build(S);
DP();
int Q,K; scanf("%d",&Q);
while(Q--){
scanf("%d",&K);
dfs(1,K,0);
}
return 0;
}

  

●SPOJ 7258 Lexicographical Substring Search的更多相关文章

  1. spoj 7258 Lexicographical Substring Search (后缀自动机)

    spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...

  2. SPOJ 7258 Lexicographical Substring Search(后缀自动机)

    [题目链接] http://www.spoj.com/problems/SUBLEX/ [题目大意] 给出一个字符串,求其字典序排名第k的子串 [题解] 求出sam上每个节点被经过的次数,然后采用权值 ...

  3. SPOJ 7258 Lexicographical Substring Search

    Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...

  4. SPOJ 7258 Lexicographical Substring Search [后缀自动机 DP]

    题意:给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个. 第一道自己做的1A的SAM啦啦啦 很简单,建SAM后跑kth就行了 也需要按val基数排序倒着 ...

  5. SPOJ SUBLEX 7258. Lexicographical Substring Search

    看起来像是普通的SAM+dfs...但SPOJ太慢了......倒腾了一个晚上不是WA 就是RE ..... 最后换SA写了...... Lexicographical Substring Searc ...

  6. SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组

    SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...

  7. 【SPOJ】7258. Lexicographical Substring Search(后缀自动机)

    http://www.spoj.com/problems/SUBLEX/ 后缀自动机系列完成QAQ...撒花..明天or今晚写个小结? 首先得知道:后缀自动机中,root出发到任意一个状态的路径对应一 ...

  8. SPOJ SUBLEX Lexicographical Substring Search - 后缀数组

    题目传送门 传送门I 传送门II 题目大意 给定一个字符串,多次询问它的第$k$大本质不同的子串,输出它. 考虑后缀Trie.依次考虑每个后缀新增的本质不同的子串个数,显然,它是$n - sa[i] ...

  9. spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看

    SPOJ.com - Problem SUBLEX 这么裸的一个SAM,放在了死破OJ上面就是个坑. 注意用SAM做的时候输出要用一个数组存下来,然后再puts,不然一个一个字符输出会更慢. 还有一个 ...

随机推荐

  1. 从0开始的LeetCode生活—001-Two Sum

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  2. Alpha冲刺置顶随笔

    项目名称:城市安全风险管控系统 小组成员: 张梨贤.林静.周静平.黄腾飞 Alpha冲刺随笔 Alpha冲刺Day1:http://www.cnblogs.com/linlkg/p/7896980.h ...

  3. v7000数据恢复_MDisk重建数据恢复方法(北亚数据恢复)

    很多工程师都有这样的疑问,MDisk重建后还能不能恢复数据呢?应该怎么做才能恢复数据呢?本文这里就以IBM V7000存储为例,详细讲解因为某个MDisk被重建导致的数据丢失的恢复方法.我们本案例中的 ...

  4. 【ASP.NET Core】依赖注入高级玩法——如何注入多个服务实现类

    依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来.服务类型的实例转由容器自动管理,无需我们在代码中显式处理. 因此,有了依 ...

  5. VS 2008 开发WinCE程序 编译部署速度慢的解决办法

    1.找到以下文件 C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets 2.用记事本打开该 ...

  6. 开发一个http代理服务器

    参考链接: http://www.cnblogs.com/jivi/archive/2013/03/10/2952860.html https://www.2cto.com/kf/201405/297 ...

  7. JSON(五)——同步请求中使用JSON格式字符串进行交互(不太常见的用法)

    在同步请求中使用JSON格式进行数据交互的场景并不多,同步请求是浏览器直接与服务器进行数据交互的大多是用jsp的标签jstl和el表达式对请求中的数据进行数据的渲染.我也是在一次开发中要从其它服务器提 ...

  8. Python/MySQL(四、MySQL数据库操作)

    Python/MySQL(四.MySQL数据库操作) 一.数据库条件语句: case when id>9 then ture else false 二.三元运算: if(isnull(xx)0, ...

  9. POJ-3641 Pseudoprime numbers---快速幂

    题目链接: https://vjudge.net/problem/POJ-3641 题目大意: 问p是不是伪素数.伪素数条件:①p不是素数.② ap = a (mod p). 思路: 直接快速幂模板+ ...

  10. flask开发表单

    from flask import Flask from flask import render_template from flask import request from flask impor ...