GDOI2012 字符串

2824. 【GDOI2012】字符串(string) (Standard IO)

Time Limits: 1000 ms  Memory Limits: 262144 KB

Description

mmm正在学习字典序。现在老师给她布置了一个作业:给出一个字符串,问该字符串的所有不同的子串中,按字典序排第K的字串。由于众所周知的原因,mmm需要你为她解决这个问题。

Input

第1行输入一个只有小写字母组成的字符串。

第2行输入N,为询问个数。

第3到N+2行每行输入一个整数Ki。

Output

输出N行,第i行输出按字典序排第Ki的子串,如果Ki超出了子串数量,输出-1.

Sample Input

abbb
8
1
2
3
4
5
6
7
8

Sample Output

a
ab
abb
abbb
b
bb
bbb
-1

Data Constraint

Hint

数据范围

1,对于30%的数据,字符串长度≤100

2,对于60%的数据,字符串长度≤3000

3,对于100%的数据,字符串长度≤20000

4,对于100%的数据,1≤N≤10

类似于求一个字符串中不同的子串数,直接上sa即可

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

char s[20011];
char c;
int a[20011],b[20011],sa[20011],co[20011];
int rank[20011],h[20011],nr[20011];
int i,x,j,k,l,n,m;
bool p;
int ans[111][3];

struct data{
    int x,idx;
}q[111];

bool cmp(data a,data b)
{
    return a.x<b.x;
}

void Read()
{
    while(c=getchar(),c<‘a‘||c>‘z‘);
    s[++n]=c;
    while(c=getchar(),c>=‘a‘&&c<=‘z‘)s[++n]=c;
}

void sort(int *a)
{
    int i,mn;
    if(27>n)mn=27;
    else mn=n;
    for(i=0;i<=mn;i++)co[i]=0;
    for(i=1;i<=n;i++)co[a[i]+1]++;
    for(i=1;i<=mn;i++)co[i]+=co[i-1];
    for(i=1;i<=n;i++)nr[i]=0;
    for(i=1;i<=n;i++){
        co[a[sa[i]]]++;
        nr[co[a[sa[i]]]]=sa[i];
    }
    for(i=1;i<=n;i++)sa[i]=nr[i];
}

void getrank()
{
    int i;
    x=0;
    for(i=1;i<=n;i++){
        if(i==1||a[sa[i]]!=a[sa[i-1]]||b[sa[i]]!=b[sa[i-1]])x++;
        rank[sa[i]]=x;
    }
}

void Suffix()
{
    int i,j,k,last,l;
    for(i=1;i<=n;i++){
        sa[i]=i;
        a[i]=s[i]-96;
        b[i]=0;
    }
    sort(a);
    getrank();
    l=1;
    while(x!=n){
        for(i=1;i<=n;i++){
            a[i]=rank[i];
            if(i+l<=n)b[i]=rank[i+l];
            else b[i]=0;
        }
        sort(b);
        sort(a);
        getrank();
        l*=2;
    }
    last=0;
    for(i=1;i<=n;i++){
        if(last)last--;
        if(rank[i]==1)continue;
        j=i;
        k=sa[rank[i]-1];
        while(j+last<=n&&k+last<=n&&s[j+last]==s[k+last])last++;
        h[rank[i]]=last;
    }
}

int main()
{
    Read();
    Suffix();
    scanf("%d",&m);
    for(i=1;i<=m;i++){
        scanf("%d",&q[i].x);
        q[i].idx=i;
    }
    sort(q+1,q+1+m,cmp);
    l=0;
    k=1;
    p=true;
    for(i=1;i<=m;i++){
        while(k<=n&&l+n-sa[k]+1-h[k]<q[i].x){
            l=l+n-sa[k]+1-h[k];
            k++;
        }
        if(k>n)p=false;
        if(p==false)break;
        ans[q[i].idx][1]=sa[k];
        ans[q[i].idx][2]=sa[k]+h[k]+q[i].x-l-1;
    }
    for(j=i;j<=m;j++){
        ans[q[i].idx][1]=-1;
    }
    for(i=1;i<=m;i++){
        if(ans[i][1]==-1)printf("-1\n");
        else{
            for(j=ans[i][1];j<=ans[i][2];j++)printf("%c",s[j]);
            printf("\n");
        }
    }
}

GDOI2012 字符串

时间: 2024-10-02 19:07:35

GDOI2012 字符串的相关文章

后缀自动机学习小记

简介 后缀三姐妹:后缀数组,后缀自动机,后缀树. 后缀自动机:Suffix Automation,也叫SAM. 创立算法的思路来源:能不能构出一个自动机(本质就是一个有向图),能识别一个串的所有后缀. 识别所有后缀基础想法 把所有的后缀都放进一个trie里面,比如串aabbabd. 这样的状态太多了,怎么把状态数缩小. 减小状态数的方法 定义一个子串的right集合为这个子串在原串中出现的右端点集合. 如果两个子串A和B的right集合完全相同的话,那么他们明显一个是另一个的后缀,假设A是B的后

条件、循环、函数定义、字符串操作练习

注意标准库的两种导入与使用方式,建议大家采用<库名>.<函数名>的方式. 对前面的代码进行优化,用for,while,if,def实现: 用循环画五角星 1 import turtle 2 3 turtle.fillcolor("red") 4 turtle.begin_fill() 5 for i in range(5): 6 turtle.forward(100) 7 turtle.right(144) 8 turtle.end_fill() 用循环画同心圆

sql常用格式化函数及字符串函数

一.常用格式化函数 1.日期转字符串 select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS') //2017-09-18 22:41:50 YYYY:年(4和更多位) MM:月份号(01-12) DD:一个月里的日(01-31) HH24:一天的小时数(00-23) MI:分钟(00-59) SS:秒(00-59) 2.字符串转日期 select to_date('2017-09-18','YYYY-MM-DD') //2017-09-

PHP 格式化字符串sprintf()

字符串函数 sprintf() 函数把格式化的字符串写入一个变量中 函数说明:sprintf(格式, 要转换的字符串)  参考PHP手册 返回: 格式化后的字符串 举例: 如:保留2位小数, $str = '99.9';echo sprintf('%01.2f', $str);结果为:99.90 echo round($str, 2); 结果为:99.9

js中字符串的替换

定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串. 语法 stringObject.replace(regexp/substr,replacement)参数 描述 regexp/substr 必需.规定子字符串或要替换的模式的 RegExp 对象. 请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象. replacement 必需.一个字符串值.规定了替换文本或生成替换文本的函数. 返

数组、字符串、集合

数组与集合的转换.数组与字符串的转换 ========数组变集合 String[] arr = {"abc","cc","kkkk"}; //把数组变成list集合有什么好处? /* 可以使用集合的思想和方法来操作数组中的元素. 注意:将数组变成集合,不可以使用集合的增删方法. 因为数组的长度是固定. contains. get indexOf() subList(); 如果你增删.那么会产生UnsupportedOperationExcepti

《Java编程思想》第十三章 字符串

<Java编程思想>读书笔记 1.String作为方法的参数时,会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置,从未动过. 2.显式地创建StringBuilder允许预先为他指定大小.如果知道字符串多长,可以预先指定StringBuilder的大小避免多次重新分配的冲突. 1 /** 2 * @author zlz099: 3 * @version 创建时间:2017年9月1日 下午4:03:59 4 */ 5 public class UsingStringBuilder {

SpringMVC后台使用对象接受参数字符串转日期

在springMVC配置文件中加入: <bean id="dateConvert" class="com.iomp.util.DateConvert"/> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property

python判断字符串,str函数isdigit、isdecimal、isnumeric的区别

s为字符串s.isalnum() 所有字符都是数字或者字母s.isalpha() 所有字符都是字母s.isdigit() 所有字符都是数字s.islower() 所有字符都是小写s.isupper() 所有字符都是大写s.istitle() 所有单词都是首字母大写,像标题s.isspace() 所有字符都是空白字符.\t.\n.\r 判断是整数还是浮点数a=123b=123.123 >>>isinstance(a,int)True>>>isinstance(b,floa