Lexicographical Substrings Search

\[Time Limit: 149 ms \quad Memory Limit: 1572864 kB
\]

题意

给出一个字符串,求出这个字符串上字典序第 \(k\) 小的子串。

思路

对于给出的字符串,求出后缀数组,根据后缀数组的 \(height\) 数组,我们可以很容易得到一个字符的总子串个数是 \(\sum_{i=1}^{n} (n-sa[i]+1-height[i])\),利用这个式子,就可以求出第 \(k\) 小的子串了。

/***************************************************************
> File Name : a.cpp
> Author : Jiaaaaaaaqi
> Created Time : 2019年05月22日 星期三 18时17分02秒
***************************************************************/ #include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pii pair<int, int> typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 1e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std; int n, m;
int cas, tol, T; char s[maxn];
int a[maxn], sa[maxn], rk[maxn], tax[maxn], height[maxn], tp[maxn]; void rsort(int n, int m) {
for(int i=0; i<=m; i++) tax[i] = 0;
for(int i=1; i<=n; i++) tax[rk[tp[i]]]++;
for(int i=1; i<=m; i++) tax[i] += tax[i-1];
for(int i=n; i>=1; i--) sa[tax[rk[tp[i]]]--] = tp[i];
} int cmp(int *f, int x, int y, int w) {
return f[x]==f[y] && f[x+w]==f[y+w];
} void SA(int *a, int n, int m) {
for(int i=1; i<=n; i++) rk[i] = a[i], tp[i] = i;
rsort(n, m);
for(int w=1, p=1, i; p<n; w<<=1, m=p) {
for(p=0, i=n-w+1;i<=n; i++) tp[++p] = i;
for(i=1; i<=n; i++) if(sa[i]>w) tp[++p] = sa[i]-w;
rsort(n, m), swap(tp, rk);
rk[sa[1]] = p = 1;
for(i=2; i<=n; i++) rk[sa[i]] = cmp(tp, sa[i], sa[i-1], w) ? p : ++p;
}
int j, k=0;
for(int i=1; i<=n; height[rk[i++]] = k)
for(k=k ? k-1 : k, j=sa[rk[i]-1]; a[i+k]==a[j+k]; k++);
} int main() {
scanf("%s", s+1);
n = strlen(s+1);
for(int i=1; i<=n; i++) {
a[i] = s[i];
}
SA(a, n, 260);
// for(int i=1; i<=n; i++) {
// printf("sa[%d] = %d height[%d] = %d\n", i, sa[i], i, height[i]);
// }
scanf("%d", &T);
while(T--) {
scanf("%d", &m);
for(int i=1; i<=n; i++) {
if(m > n-sa[i]+1-height[i]) {
m -= (n-sa[i]+1-height[i]);
} else {
int last = sa[i] + height[i] - 1;
last += m;
// printf("%d %d\n", sa[i], last);
for(int j=sa[i]; j<=last; j++) {
printf("%c", s[j]);
}
printf("\n");
break;
}
}
}
return 0;
}

Lexicographical Substring Search SPOJ - SUBLEX (后缀数组)的更多相关文章

  1. Lexicographical Substring Search SPOJ - SUBLEX (后缀自动机)

    Lexicographical Substrings Search \[ Time Limit: 149 ms \quad Memory Limit: 1572864 kB \] 题意 给出一个字符串 ...

  2. Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)

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

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

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

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

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

  5. SPOJ SUBLEX 7258. Lexicographical Substring Search

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

  6. [SPOJ7258]Lexicographical Substring Search

    [SPOJ7258]Lexicographical Substring Search 试题描述 Little Daniel loves to play with strings! He always ...

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

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

  8. SPOJ PHRASES 后缀数组

    题目链接:http://www.spoj.com/problems/PHRASES/en/ 题意:给定n个字符串,求一个最长的子串至少在每个串中的不重叠出现次数都不小于2.输出满足条件的最长子串长度 ...

  9. SPOJ REPEATS 后缀数组

    题目链接:http://www.spoj.com/problems/REPEATS/en/ 题意:首先定义了一个字符串的重复度.即一个字符串由一个子串重复k次构成.那么最大的k即是该字符串的重复度.现 ...

随机推荐

  1. C# System.Reflection.Assembly动态加载资源文件

    需求:需要做甘特图的显示,并且在甘特中加载图片.图片太多,写判断代码太多.用反射吧. 核心代码: try { if (stateColour < 0) return null; System.R ...

  2. 封装:WPF绘制曲线视图

    原文:封装:WPF绘制曲线视图 一.目的:绘制简单轻量级的曲线视图 二.实现: 1.动画加载曲线 2.点击图例显示隐藏对应曲线 3.绘制标准基准线 4.绘制蒙板显示标准区域 曲线图示例: 心电图示例: ...

  3. 从0开始编写dapper核心功能、压榨性能、自己动手丰衣足食

    我偶然听说sqlsugar的性能比dapper强.对此我表示怀疑(由于我一直使用的dapper存在偏见吧),于是自己测试了sqlsugar.freesql.dapper发现他们的给我的结果是 sqls ...

  4. jsp,servlet文件上传问题完善

    1. 上传文件时文件名中文乱码 upload.setHeaderEncoding("utf-8"); 有个疑惑: 不管设置不设置都不乱码,但是刘帅龙老师讲的时候出现了乱码 . 2. ...

  5. PHP面试题2019年腾讯工程师面试题和答案

    一.单选题(共29题,每题5分) 1.PHP执行的时候有如下执行过程:Scanning(Lexing) - Compilation - Execution - Parsing,其含义分别为: A.将P ...

  6. MTSC2019-深圳站 议题征集

    议题截止时间 11月初 议题投递地址 topic@testerhome.com   臣一路走来,没有敌人,看见的都是朋友和师长 —司马懿 关于中国移动互联网测试大会 MTSC 大会(中国移动互联网测试 ...

  7. TCP协议的常见面试题

    1. 为什么连接的时候是三次握手,关闭的时候却是四次握手? 因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文.其中ACK报文是用来应答的,SYN报文是用来同 ...

  8. 把微信小程序异步API转为Promise,简化异步编程

    把微信小程序异步API转化为Promise.用Promise处理异步操作有多方便,谁用谁知道. 微信官方没有给出Promise API来处理异步操作,而官方API异步的又非常多,这使得多异步编程会层层 ...

  9. Django:RestFramework之-------认证

    3 restframework-认证 3.1APIView 认证: 认证是否已经登陆,如果已经登陆返回元组,如果没有登陆报错 源码流程: 执行dispatch方法: def dispatch(self ...

  10. layui 表格中实现照片预览,点击查看原图

    人员表格中实现照片预览,并且可点击放大.查看原图 <table id="dutyInfoTable" class="layui-hide">< ...