hdu 4622 Reincarnation(后缀自动机,入门级)
2015-08-09 14:46
435 查看
题意:
求字符串任意字串的不同字串数。
思路:
用后缀自动机可以做到 O(n2)O(n^2)预处理,O(1)O(1)回答查询。
不过我的代码跑了 1000+ms
别人的代码可以跑到 100ms-200ms。。
VJ的记录
求字符串任意字串的不同字串数。
思路:
用后缀自动机可以做到 O(n2)O(n^2)预处理,O(1)O(1)回答查询。
不过我的代码跑了 1000+ms
别人的代码可以跑到 100ms-200ms。。
VJ的记录
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <set> #include <queue> #include <cmath> using namespace std; #define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i)) const int N = 2005; typedef long long LL; struct State { State *link, *go[26]; int len; void clear() { link = 0; len = 0; memset(go, 0, sizeof(go)); } int calc() { if ( link == 0 ) return 0; return len - link->len; } } *root, *last, *cur; const int MaxLength = N; State statePool[MaxLength*2]; void init() { cur = statePool; root = last = cur ++; root->clear(); } int tot = 0; void sa_insert(int ch) { //cout << "Insert " << (char)ch << endl; ch -= 'a'; State *p = last; State *np = cur ++; np->clear(); np->len = p->len + 1; while ( p && !p->go[ch] ) { p->go[ch] = np; p = p->link; } if ( p == 0 ) { np->link = root; } else { State *q = p->go[ch]; if ( p->len + 1 == q->len ) { np->link = q; } else { State *nq = cur ++; nq->clear(); memcpy(nq->go, q->go, sizeof(q->go)); tot -= q->calc(); nq->len = p->len + 1; nq->link = q->link; q->link = nq; np->link = nq; tot += q->calc() + nq->calc(); while( p && p->go[ch] == q ) { p->go[ch] = nq; p = p->link; } } } tot += np->calc(); last = np; } int cnt , n; char buf ; int main() { #ifdef _LOCA_ENV_ freopen("input.in", "r", stdin); #endif // _LOCA_ENV int t; scanf("%d", &t); while ( t -- ) { scanf("%s", buf); //cout << buf << endl; scanf("%d", &n); int len = strlen(buf); rep(i, 0, len-1) { init(); tot = 0; rep(j, i, len-1) { sa_insert(buf[j]); cnt[i][j] = tot; } } rep(i, 1, n) { int l, r; scanf("%d%d", &l, &r); -- l, -- r; printf("%d\n", cnt[l][r]); } } return 0; }
相关文章推荐
- Use After Free Tutorial
- HDOJ 5361 In Touch dijkstra最短路
- LeetCode:Add Two Numbers
- Android之——清理手机SD卡缓存
- python中的break|continue|pass|return
- Android相关博客网址收集
- neuoj 1153
- 【机房收费系统】 之 报表
- C编程的指针涛 ---第十笔记
- 数据点间的相似度-距离计算方法
- ASP.NET MVC5(2)视图
- linux SMP系统学习笔记
- 不做“越跌越买”的傻瓜
- C++引用详解
- 求薪水在部门的平均薪水之上的雇员姓名和及薪水
- poj1061 青蛙的约会
- SeaJS 与 RequireJS 的差异1
- iOS定位和位置信息获取
- 贪心算法之Packets
- Linux之uptime主机运行时间及平均负载含义