【bzoj3998】[TJOI2015]弦论
题目描述:
对于一个给定长度为N的字符串,求它的第K小子串是什么。
样例输入:
aabc
0 3
样例输出:
aab
题解:
构造后缀自动机,然后在后缀自动机上跑dfs
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> #ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif #ifdef CT
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif #define R register
#define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
#define gmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define gmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1<<15],*S=B,*T=B;
inline int FastIn()
{
R char ch;R int cnt=0;R bool minus=0;
while (ch=getc(),(ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ?minus=1:cnt=ch-'0';
while (ch=getc(),ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus?-cnt:cnt;
}
#define maxn 1000010
char str[maxn];
int a[maxn][26] , val[maxn] , fa[maxn] , l[maxn] ,last , tot , p , np , q , nq , t , k ;
int v[maxn] , que[maxn] , sum[maxn] ;
inline void extend (R int c)
{
p = last ;
np = last = ++tot ;
l[np] = l[p] + 1 ;
val[np] = 1;
for ( ; !a[p][c] && p ; ) a[p][c] = np , p = fa[p] ;
if (!p) fa[np] = 1 ;
else
{
q = a[p][c] ;
if (l[p] + 1 == l[q] ) fa[np] = q ;
else
{
nq = ++tot ;
l[nq] = l[p] + 1 ;
memcpy ( a[nq] , a[q] ,sizeof (a[q]) );
fa[nq] = fa[q] ;
fa[np] = fa[q] = nq ;
for ( ; a[p][c]==q ; ) a[p][c] = nq , p = fa[p] ;
}
}
}
inline void prepare()
{
for (R int i = 1 ; i <= tot ; i++ ) v[ l[i] ] ++ ;
for (R int i = 1 ; str[i] ; i++ ) v[i] += v[i-1] ;
for (R int i = tot ; i ; i-- ) que [ v[ l[i] ] -- ] = i ;
for (R int i = tot ; i ; i-- )
{
R int tmp = que[i];
if (t == 1) val[fa[tmp]] += val[tmp] ;
else val[tmp] = 1 ;
}
val[1] = 0 ;
for (R int i = tot ; i ; i--)
{
R int tmp = que[i] ;
sum[tmp] = val[tmp] ;
for (R int j = 0 ; j < 26 ; j++ )
sum[tmp] += sum [ a[tmp][j] ] ;
}
}
void dfs(R int x , R int k)
{
if (k <= val [x] ) return ;
k -= val[x] ;
for (R int i = 0 ; i < 26 ; i++ )
{
if (int tmp = a[x][i] )
{
if (k <= sum[tmp] )
{
printf("%c" , i + 'a' );
dfs(tmp , k);
return ;
}
k -= sum[tmp];
}
}
}
int main()
{
last = ++ tot;
scanf ( "%s\n", str + 1);
scanf( "%d %d" , &t , &k);
for (R int i = 1 ; str[i] ; i++) extend( str[i] - 'a');
prepare();
if ( sum[1] < k) puts("-1") ;
else dfs(1 , k ) ;
return 0;
}
/*
aasdfsdafsdafsadfasdfsadf
0 4
aasd
*/
【bzoj3998】[TJOI2015]弦论的更多相关文章
- [bzoj3998][TJOI2015]弦论_后缀自动机
弦论 bzoj-3998 TJOI-2015 题目大意:给定一个字符串,求其$k$小子串. 注释:$1\le length \le 5\cdot 10^5$,$1\le k\le 10^9$. 想法: ...
- bzoj3998: [TJOI2015]弦论(SAM+dfs)
3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...
- BZOJ3998 TJOI2015弦论(后缀数组+二分答案)
先看t=1的情况.显然得求出SA(因为我不会SAM).我们一位位地确定答案.设填到了第len位,二分这一位填什么之后,在已经确定的答案所在的范围(SA上的某段区间)内二分,找到最后一个小于当前串的后缀 ...
- bzoj3998: [TJOI2015]弦论
SAM小裸题qwq #include <iostream> #include <cstdio> #include <cmath> #include <cstr ...
- bzoj3998 [TJOI2015]弦论(SAM)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3998 [题意] 询问排名第k的子串是谁,0代表相同子串不同位置算作相同,1代表相同子串 ...
- [bzoj3998][TJOI2015]弦论-后缀自动机
Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...
- 2018.12.15 bzoj3998: [TJOI2015]弦论(后缀自动机)
传送门 后缀自动机基础题. 求第kkk小的子串(有可能要求本质不同) 直接建出samsamsam,然后给每个状态赋值之后在上面贪心选最小的(过程可以类比主席树/平衡树的查询操作)即可. 代码: #in ...
- BZOJ3998:[TJOI2015]弦论(SAM)
Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...
- BZOJ3998 TJOI2015 弦论 【后缀自动机】【贪心】
Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...
- BZOJ3998 [TJOI2015]弦论 【后缀自动机】
题目 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入格式 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...
随机推荐
- C#的Split()方法
var arr = list[i]["Tag"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- java8-----lambda语法
// -----lambda语法1------ https://www.baidu.com/link?url=6iszXQlsmyaoWVZMaPs3g8vLRQXzdzTnKzQYTF8lg-5QQ ...
- 【7.24校内交流赛】T1&T2
T1: 一个脑洞很大的题,将输入的所有数异或起来输出就好了: (话说我为什么这么喜欢用异或啊) #include<bits/stdc++.h> using namespace std; i ...
- thinkPHP三级城市联动
html+js: <!doctype html> <html lang="en"> <head> <meta charset=" ...
- 2、Java调用C语言(JNative法)
这个方法也是挺麻烦的…… 一.下载JNative.jar,把它放在你jdk下的\jre\lib\ext目录下 二.在 F:\MinGW\JNative 新建 Test.java: public cla ...
- sql 字符串 切割函数 FUN_Split
IF EXISTS ( SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FUN_Split]') AND OBJECTPROPER ...
- C#GC垃圾回收和析构函数和IDisposable的使用
一,什么是GC 1,GC是垃圾回收器,一般来说系统会自动检测不会使用的对象或变量进行内存的释放,不需要手动调用,用Collect()就是强制进行垃圾回收,使内存得到及时的释放,让程序效率更高. 2,G ...
- 【nginx】上传文件error报413 Request Entity Too Large
nginx配置增大上传文件限制 如果访问地址是通过nginx转发配置的 server{ ... ... client_max_body_size 50M; ... ... } ingress配置增大上 ...
- 封装class类--不分割类名
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Java基础学习(1)
Java基础知识 Java平台 1995年由Sun公司创建 Java的体系结构 JVM Java Virtue Machine Java代码的执行顺序 JDK Java Development Kit ...