bzoj 3998: [TJOI2015]弦论 后缀自动机
2017-03-08 20:31
375 查看
题目大意:
对于一个给定长度为N的字符串,求它的第K小子串是什么。
题解:
这道题我们可以类比着bzoj 2882: 工艺来做
那道题是求最小的一个字符串,而这道题是要求一个k小的字符串
所以我们瞎搞一搞就好了啊...像在平衡树上查询k小一样.
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; inline void read(ll &x){ x=0;char ch;bool flag = false; while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true; while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x; } const ll maxn = 500010; struct Node{ int nx[26]; int fa,len; }T[maxn<<1]; int last,nodecnt; ll siz[maxn<<1]; int num[maxn<<1]; void init(){ last = nodecnt = 0; T[0].fa = -1;T[0].len = 0; } void insert(char cha){ int c = cha - 'a',cur = ++ nodecnt,p; T[cur].len = T[last].len+1; for(p=last;p!=-1 && !T[p].nx[c];p=T[p].fa) T[p].nx[c] = cur; if(p == -1) T[cur].fa = 0; else{ int q = T[p].nx[c]; if(T[q].len == T[p].len + 1) T[cur].fa = q; else{ int co = ++ nodecnt; T[co] = T[q];T[co].len = T[p].len + 1; for(;p!=-1&&T[p].nx[c] == q;p=T[p].fa) T[p].nx[c] = co; T[cur].fa = T[q].fa = co; } }last = cur; ++num[last]; } inline void build(char *s){ init();int len = strlen(s); for(int i=0;i<len;++i) insert(s[i]); } int q[maxn<<1],l,r; bool vis[maxn<<1]; void calc_num(int ty){ l = 0;r = -1; q[++r] = 0;vis[0] = true; while(l <= r){ int u = q[l++]; for(int c=0;c<26;++c){ if(T[u].nx[c] && !vis[T[u].nx[c]]){ vis[T[u].nx[c]] = true; q[++r] = T[u].nx[c]; } } } for(int i=r;i>=1;--i){ if(ty == 0) num[q[i]] = (bool)num[q[i]]; num[T[q[i]].fa] += num[q[i]]; } } void dfs(int u){ vis[u] = true; siz[u] = num[u]; for(int c=0;c<26;++c){ if(T[u].nx[c]){ if(!vis[T[u].nx[c]]) dfs(T[u].nx[c]); siz[u] += siz[T[u].nx[c]]; } }return; } bool flag = false; void find(int u,ll k){ if(k <= num[u]) return; k -= num[u]; for(int c=0;c<26;++c){ if(T[u].nx[c]){ if(k <= siz[T[u].nx[c]]){ flag = true; putchar(c+'a'); find(T[u].nx[c],k); return; }k -= siz[T[u].nx[c]]; } }return; } char s[maxn<<1]; int main(){ scanf("%s",s);build(s); ll T,K;read(T);read(K); calc_num(T);memset(vis,0,sizeof vis); num[0] = 0;dfs(0); if(siz[0] < K) return puts("-1"); find(0,K); getchar();getchar(); return 0; }
相关文章推荐
- BZOJ3998 [TJOI2015]弦论 【后缀自动机】
- 【BZOJ3998】【TJOI2015】 弦论 后缀自动机
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
- BZOJ 3998 TJOI 2015 弦论 后缀自动机
- BZOJ 题目3998: [TJOI2015]弦论(后缀自动机求排名第k的子串,可重复)
- [BZOJ3998][TJOI2015]弦论(后缀自动机)
- [BZOJ]3998 [TJOI2015] 弦论 后缀自动机
- [BZOJ3998]-[TJOI2015]弦论-后缀自动机
- [BZOJ3998][TJOI2015]弦论(后缀自动机+拓扑排序+贪心)
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
- [BZOJ3998] [TJOI2015] 弦论 - 后缀自动机
- 【BZOJ3998】【TJOI2015】弦论 后缀自动机
- 【bzoj3998】[TJOI2015]弦论 后缀自动机
- BZOJ 3998 [TJOI2015]弦论【后缀自动机(总结+安利
- 【BZOJ3998】弦论(TJOI2015)-后缀自动机
- 【bzoj3998】[TJOI2015]弦论 后缀自动机
- [bzoj3998][TJOI2015]弦论-后缀自动机
- BZOJ 3998 TJOI2015 弦论 后缀自动机
- BZOJ 3998 [TJOI2015]弦论 ——后缀自动机
- 【bzoj3998】[TJOI2015]弦论 后缀自动机