博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TJOI 2015 弦论 题解
阅读量:2307 次
发布时间:2019-05-09

本文共 1787 字,大约阅读时间需要 5 分钟。

题目大意: 求出一个字符串第 k k k 小的子串是谁。

题解

建出SAM,求出 s i z e size size 数组,即每个状态的 e n d p o s endpos endpos 集大小,如果 t = 0 t=0 t=0 的话,就将 s i z e size size 都设为 1 1 1,因为即使在多个地方出现也只算一个。要注意求完后 s i z e [ 0 ] size[0] size[0] 要等于 0 0 0,因为初始状态的空子串是不计入答案的。

然后求出 s u m sum sum 数组, s u m [ x ] sum[x] sum[x] 表示从状态 x x x 出发能得到多少个子串,也就是他能到达的状态的 s i z e size size 之和。

然后贪心跑一下dfs即可,代码如下:

#include 
#include
#define maxn 1000010int n,type,k;char s[maxn];struct state{
int len,link,next[26];}st[maxn];int id=0,last=0,now,p,q;int size[maxn],sum[maxn];void extend(int x){
now=++id; st[now].len=st[last].len+1;size[now]=1; for(p=last;p!=-1&&!st[p].next[x];p=st[p].link)st[p].next[x]=now; if(p!=-1) {
q=st[p].next[x]; if(st[p].len+1==st[q].len)st[now].link=q; else {
int clone=++id; st[clone]=st[q];st[clone].len=st[p].len+1; for(;p!=-1&&st[p].next[x]==q;p=st[p].link)st[p].next[x]=clone; st[q].link=st[now].link=clone; } } last=now;}int c[maxn],A[maxn];void get_size(){
if(!type){
for(int i=1;i<=id;i++)size[i]=1;return;} for(int i=1;i<=id;i++)c[st[i].len]++; for(int i=1;i<=id;i++)c[i]+=c[i-1]; for(int i=1;i<=id;i++)A[c[st[i].len]--]=i; for(int i=id;i>=1;i--)size[st[A[i]].link]+=size[A[i]];}bool v[maxn];void get_sum(int x){
if(v[x])return;v[x]=true; for(int i=0;i<26;i++) if(st[x].next[i])get_sum(st[x].next[i]),sum[x]+=sum[st[x].next[i]];}void dfs(int x){
k-=size[x]; if(k<=0)return; for(int i=0;i<26;i++) if(st[x].next[i]) {
if(sum[st[x].next[i]]>=k) {
printf("%c",i+'a'); dfs(st[x].next[i]); break; } else k-=sum[st[x].next[i]]; }}int main(){
scanf("%s",s+1);n=strlen(s+1); scanf("%d %d",&type,&k); st[0].link=-1; for(int i=1;i<=n;i++)extend(s[i]-'a'); get_size();size[0]=0; for(int i=0;i<=id;i++)sum[i]=size[i]; get_sum(0); if(sum[0]

转载地址:http://ojnib.baihongyu.com/

你可能感兴趣的文章
DB2 的 case when then else end 条件分支的处理
查看>>
POI读取Excel(兼容Excel2003、Excel2007)
查看>>
ActionContext(Struts中的Action类里)和ServletActionContext(HttpServlet类里的)【区别】小结
查看>>
关于ActionContext.getContext()的用法心得
查看>>
Struts2+JQuery.uploadify插件实现带进度的多文件上传示例【也可以设置去掉进度条的显示】
查看>>
用java存oracle数据库的date类型精确到秒【java.sql.Date 和java.util.Date的区别】
查看>>
jquery-easyui实现页面布局和增删改查操作(SSH2框架支持)
查看>>
EasyUI--datebox设置默认时间【dateTimeBox类似】
查看>>
easyui datetimebox处理【前台传递到后台是string类型,但是后台定义的是java.util.date,如何自动转换数据类型】
查看>>
jquery easyui 对于开始时间小于结束时间的判断示例
查看>>
java怎么判断两个Set 里的对象的值是否相同【两个set中的值是否相等】、java treeset和hashset如何判断元素是否相同【即对象是否完全相同;利用一个set去除重复元素】
查看>>
jQuery.validator.addMethod自定义验证方法【在表单验证中的使用 $("#appEdit_Form").validate({rules : {},messages:{}】
查看>>
jQuery怎么获取一些属性值类似的控件,又怎么遍历他们呢?
查看>>
WARN com.opensymphony.xwork2.ognl.OgnlValueStack异常的解决办法[提交按钮使用了图片并设置name属性,对应action无gettersetter]
查看>>
一般操作需要导入的jquery包(jquery.js包)和 jquery操作select下拉列表(取值及设置选中某一个option)
查看>>
在页面加载完成后通过jquery给多个span赋html值(当前系统时间本地格式化new Date().toLocaleDateString(); )
查看>>
SSH原理与运用(一):远程登录和SSH原理与运用(二):远程操作与端口转发
查看>>
基于jQuery的AJAX和JSON的实例[另附文章:深入浅出json]
查看>>
jquery.validate的ajax方式验证[可以一个控件下一次传递多个参数,已经成功通过验证]
查看>>
easyui自带的日历功能和生日年月日的三级联动
查看>>