zoukankan      html  css  js  c++  java
  • [BZOJ3998][TJOI2015]弦论

    [BZOJ3998][TJOI2015]弦论

    试题描述

    对于一个给定长度为N的字符串,求它的第K小子串是什么。

    输入

    第一行是一个仅由小写英文字母构成的字符串S

    第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。K的意义如题所述

    输出

    输出仅一行,为一个数字串,为第K小的子串。如果子串数目不足K个,则输出-1

    输入示例

    aabc
    0 3

    输出示例

    aab

    数据规模及约定

    N<=5*10^5

    T<2

    K<=10^9

    题解

    对于 T = 0 的情况,就是这道题;对于 T = 1 的情况就是把每个节点的权值由 1 变成 right 集合的大小。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 1000010
    #define maxa 26
    
    char S[maxn];
    int len, T, K;
    
    int rt, last, ToT, to[maxn][maxa], par[maxn], Max[maxn], val[maxn], f[maxn];
    void extend(int x) {
    	int p = last, np = ++ToT; Max[np] = Max[p] + 1; val[np] = 1; last = np;
    	while(p && !to[p][x]) to[p][x] = np, p = par[p];
    	if(!p){ par[np] = rt; return ; }
    	int q = to[p][x];
    	if(Max[q] == Max[p] + 1){ par[np] = q; return ; }
    	int nq = ++ToT; Max[nq] = Max[p] + 1; if(!T) val[nq] = 1;
    	memcpy(to[nq], to[q], sizeof(to[q]));
    	par[nq] = par[q];
    	par[q] = par[np] = nq;
    	while(p && to[p][x] == q) to[p][x] = nq, p = par[p];
    	return ;
    }
    
    int sa[maxn], Ws[maxn];
    
    int main() {
    	scanf("%s", S); T = read(); K = read();
    	len = strlen(S);
    	
    	rt = last = ToT = 1;
    	for(int i = 0; i < len; i++) extend(S[i] - 'a');
    	for(int i = 1; i <= ToT; i++) Ws[len-Max[i]]++;
    	for(int i = 1; i <= len; i++) Ws[i] += Ws[i-1];
    	for(int i = ToT; i; i--) sa[Ws[len-Max[i]]--] = i;
    	if(T)
    		for(int i = 1; i <= ToT; i++) {
    			int u = sa[i];
    			if(par[u] != rt) val[par[u]] += val[u];
    		}
    	for(int i = 1; i <= ToT; i++) {
    		int u = sa[i];
    		f[u] = val[u];
    		for(int c = 0; c < maxa; c++) f[u] += f[to[u][c]];
    	}
    	
    	if(K > f[1]) return puts("-1"), 0;
    	int p = rt;
    	while(K > 0) {
    		for(int c = 0; c < maxa; c++) if(K > f[to[p][c]])
    			K -= f[to[p][c]];
    		else {
    			putchar(c + 'a');
    			K -= val[p = to[p][c]];
    			break;
    		}
    	}
    	putchar('
    ');
    	
    	return 0;
    }
    
  • 相关阅读:
    Java实体书写规范
    Mybatis配置中遇到的问题和问题分析
    Ubuntu下eclipse的Extjs提示插件安装
    Ubuntu中root用户和user用户的相互切换
    ubuntu下启动和关闭tomcat的简单方法
    Ubuntu上安装Maven Eclipse以及配置
    IE8兼容<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
    心情
    更改Eclipse下Tomcat的部署目录
    Tomcat:IOException while loading persisted sessions: java.io.EOFException 解决
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6554200.html
Copyright © 2011-2022 走看看