SPOJ SUBLEX - Lexicographical Substring Search
2015-08-27 09:10
429 查看
SUBLEX - Lexicographical Substring Search
no tagsLittle Daniel loves to play with strings! He always finds different ways to have fun with strings! Knowing that, his friend Kinan decided to test his skills so he gave him a string S and asked him Q questions of the form:
If all distinct substrings of string S were sorted lexicographically, which one will be the K-th smallest?
After knowing the huge number of questions Kinan will ask, Daniel figured out that he can't do this alone. Daniel, of course, knows your exceptional programming skills, so he asked you to write him a program which given S will answer Kinan's questions.
Example:
S = "aaa" (without quotes)
substrings of S are "a" , "a" , "a" , "aa" , "aa" , "aaa". The sorted list of substrings will be:
"a", "aa", "aaa".
Input
In the first line there is Kinan's string S (with length no more than 90000 characters). It contains only small letters of English alphabet. The second line contains a single integer Q (Q <= 500) , the number of questions Daniel will be asked. In the next Q lines a single integer K is given (0 < K < 2^31).Output
Output consists of Q lines, the i-th contains a string which is the answer to the i-th asked question.Example
Input: aaa 2 2 3 Output: aa aaa 解题:SAM。我们可以算路径,来计算它后面有多少个字串,因为路径个数就代表了不同子串的个数
#include <bits/stdc++.h> using namespace std; const int maxn = 200010; struct node { int son[26],f,len; void init() { f = -1; len = 0; memset(son,-1,sizeof son); } }; struct SAM { node e[maxn<<1]; int tot,last; void init() { tot = last = 0; e[tot++].init(); } int newnode(int len = 0) { e[tot].init(); e[tot].len = len; return tot++; } void extend(int c) { int p = last,np = newnode(e[p].len + 1); while(p != -1 && e[p].son[c] == -1) { e[p].son[c] = np; p = e[p].f; } if(p == -1) e[np].f = 0; else { int q = e[p].son[c]; if(e[p].len + 1 == e[q].len) e[np].f = q; else { int nq = newnode(); e[nq] = e[q]; e[nq].len = e[p].len + 1; e[q].f = e[np].f = nq; while(p != -1 && e[p].son[c] == q) { e[p].son[c] = nq; p = e[p].f; } } } last = np; } } sam; char str[maxn]; int c[maxn],sa[maxn],dp[maxn],ans[maxn]; node *e = sam.e; void solve(){ int Q,k; scanf("%d",&Q); while(Q--){ scanf("%d",&k); int tot = 0,p = 0; while(k){ for(int i = 0; i < 26; ++i){ if(dp[e[p].son[i]] < k) k -= dp[e[p].son[i]]; else { ans[tot++] = i; p = e[p].son[i]; --k; break; } } } for(int i = 0; i < tot; ++i) putchar(ans[i] + 'a'); putchar('\n'); } } int main() { sam.init(); scanf("%s",str); int len = strlen(str); for(int i = c[len] = 0; str[i]; ++i) { sam.extend(str[i] - 'a'); c[i] = 0; } for(int i = 1; i < sam.tot; ++i) { c[e[i].len]++; dp[i] = 1; } for(int i = 1; i <= len; ++i) c[i] += c[i-1]; for(int i = sam.tot-1; i > 0; --i) sa[c[e[i].len]--] = i; for(int i = sam.tot-1; i > 0; --i){ int v = sa[i]; for(int j = 0; j < 26; ++j) if(e[v].son[j] != -1) dp[v] += dp[e[v].son[j]]; } solve(); return 0; }
View Code
相关文章推荐
- 使用CSplitterWnd实现拆分窗口(多视图显示)
- Git时间,对代码的管理
- VS2010删除原来的继承的值,已试过没问题
- 字串的连接最长路径查找
- 买房注意事项 (2)
- xml与json的区别,总结
- CF 557C Arthur and Table(贪心)
- HDOJ 1879 继续畅通工程 (最小生成树)
- Mac通过iResign重签名ipa未越狱安装越狱程序软件
- Linux用户管理各命令的使用
- 智能路由器要成功 该怎样修炼穿墙术
- 环信架构
- python setuptools工具
- error MSB8031: Building an MFC project for a non-Unicode character set is deprecated
- 黑马程序员-----Java基础-----GUI
- Java-clone总结
- Java-clone总结
- Java-clone总结
- if (log.isDebugEnabled())?添加这个判断的原因
- iOS开发之runtime的运用-获取当前网络状态