spoj7258 Lexicographical Substring Search(SUBLEX),后缀自动机
来源:互联网 发布:日本历史地震数据统计 编辑:程序博客网 时间:2024/05/19 05:04
spoj7258. Lexicographical Substring Search
求一个串的所有不同子串中字典序第k大的。
利用后缀自动机,拓扑排序后通过子边dp,可以计算当前状态可接受的后缀还有多少个串。
然后不断转移即可。
由于卡常数,需要两个优化:
1.预处理将空儿子去掉,减少转移复杂度。
2.优化输出,将要输出的串保存在一个char数组中,最后一起输出。会比一个字符一个字符快些。
最后吐槽一句,SPOJ这破评测机……
求一个串的所有不同子串中字典序第k大的。
利用后缀自动机,拓扑排序后通过子边dp,可以计算当前状态可接受的后缀还有多少个串。
然后不断转移即可。
由于卡常数,需要两个优化:
1.预处理将空儿子去掉,减少转移复杂度。
2.优化输出,将要输出的串保存在一个char数组中,最后一起输出。会比一个字符一个字符快些。
最后吐槽一句,SPOJ这破评测机……
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define Maxn 90009int root,last;//samint tots;int fi[Maxn*2],ne[510000],to[510000],al[510000];int te;int tot[Maxn*2];char str[Maxn];struct sam_node{ int fa,son[26]; int len; void init(int _len){len=_len;fa=-1;memset(son,-1,sizeof(son));}}t[Maxn*2];//length*2void sam_init(){ tots=0; root=last=0; t[tots].init(0);}void extend(int w){ //int w=ch-'a'; int p=last; int np=++tots;t[tots].init(t[p].len+1); int q,nq; while(p!=-1&&t[p].son[w]==-1){t[p].son[w]=np;p=t[p].fa;} if (p==-1) t[np].fa=root; else{ q=t[p].son[w]; if (t[p].len+1==t[q].len){t[np].fa=q;} else{ nq=++tots;t[nq].init(0); t[nq]=t[q]; t[nq].len=t[p].len+1; t[q].fa=nq;t[np].fa=nq; while(p!=-1&&t[p].son[w]==q){t[p].son[w]=nq;p=t[p].fa;} } } last=np;}int w[Maxn],r[Maxn*2],l;void topsort(){ int i; for(i=0;i<=l;++i) w[i]=0; for(i=1;i<=tots;++i)w[t[i].len]++; for(i=1;i<=l;++i) w[i]+=w[i-1]; for(i=tots;i>=1;--i)r[w[t[i].len]--]=i;}void work(int k){ int i; int p=root,tmp; int e,tl; tl=0; while(--k){ for(e=fi[p];~e;e=ne[e]){ tmp=tot[to[e]]; if (tmp>=k) {p=to[e];str[tl++]=al[e]+'a';break;} else {k-=tmp;} } } str[tl]='\0'; puts(str);}inline void addedge(int u,int v,int j){ te++; ne[te]=fi[u];fi[u]=te;to[te]=v;al[te]=j;}char s[Maxn];int i,u,ttot,j,q,k;int main(){ scanf("%s",s); sam_init(); l=strlen(s); for(i=0;i<l;++i){ extend(s[i]-'a'); } topsort(); for(i=0;i<=tots;++i) fi[tots]=-1; te=0; r[0]=0; for(i=tots;i>=0;--i){ u=r[i]; ttot=1; for(j=25;j>=0;--j){ if (~t[u].son[j]) { ttot+=tot[t[u].son[j]]; addedge(u,t[u].son[j],j); } } tot[u]=ttot; } scanf("%d",&q); for(i=1;i<=q;++i){ scanf("%d",&k); work(k+1); } return 0;}
0 0
- spoj7258 Lexicographical Substring Search(SUBLEX) 后缀自动机
- spoj7258 Lexicographical Substring Search(SUBLEX),后缀自动机
- [SPOJ7258]SUBLEX - Lexicographical Substring Search(后缀自动机)
- [SPOJ7258]SUBLEX - Lexicographical Substring Search
- [spoj7258]Lexicographical Substring Search && 后缀自动机
- spoj7258:Lexicographical Substring Search 后缀自动机
- 【SPOJ7258】Lexicographical Substring Search-后缀自动机+拓补序递推
- SPOJ SUBLEX Lexicographical Substring Search 后缀自动机
- 【后缀自动机】[SPOJ SUBLEX]Lexicographical Substring Search
- spoj7258:Lexicographical Substring Search(后缀自动机+拓扑排序)
- SPOJ 7258 SUBLEX - Lexicographical Substring Search (后缀自动机)
- SPOJ 题目7528 SUBLEX - Lexicographical Substring Search(后缀自动机求排名k的子串)
- spoj 7258 Lexicographical Substring Search(后缀数组 | 后缀自动机)
- SPOJ SUBLEX Lexicographical Substring Search
- SPOJ SUBLEX Lexicographical Substring Search
- spoj 7258 Lexicographical Substring Search (后缀自动机)
- SPOJ Lexicographical Substring Search --后缀自动机
- SPOJ Lexicographical Substring Search 后缀自动机
- C++ 基本类型(Primitive Type) 的(const reference type) 参数有何用处?
- linux设备驱动——输入子系统
- hdu 4902 Nice boat(树形结构-线段树)
- Java1.5若干新特性
- codeforces round 261
- spoj7258 Lexicographical Substring Search(SUBLEX),后缀自动机
- 关于SQL server的Update用法
- POJ 1185 炮兵阵地 (状态压缩DP)
- 指针函数与函数指针的区别
- 系统的移植小感
- Qt-时间
- KMP算法求next数组
- C++ STL相关容器详解
- Android UsageStatsService:要点解析