SPOJ NSUBSTR
2015-06-20 16:44
295 查看
题目大意:
给定一个字符串,求每个对应的长度能产生的相同子串的最大个数
这里构建好后缀自动机之后,再将整个字符串从头到尾扫一遍,然后将每个对应的点上的sc值+1
表示从头走到尾的前提下,所能产生的子串能够得到的最大数量为1
然后再去考虑其他子串
每个后缀自动机上的节点上的长度表示的是当前点所能接收的最大长度的后缀
我们只考虑这个最大长度即可,因为其他没考虑的长度,最后都不断通过dp[i] = max(dp[i] , dp[i+1]) 得到即可
拓扑排序后,从尾节点开始不断往前,相当于由子节点不断更新父节点所能得到的值
也就是b[i]->f->sc += b[i]->sc;
给定一个字符串,求每个对应的长度能产生的相同子串的最大个数
这里构建好后缀自动机之后,再将整个字符串从头到尾扫一遍,然后将每个对应的点上的sc值+1
表示从头走到尾的前提下,所能产生的子串能够得到的最大数量为1
然后再去考虑其他子串
每个后缀自动机上的节点上的长度表示的是当前点所能接收的最大长度的后缀
我们只考虑这个最大长度即可,因为其他没考虑的长度,最后都不断通过dp[i] = max(dp[i] , dp[i+1]) 得到即可
拓扑排序后,从尾节点开始不断往前,相当于由子节点不断更新父节点所能得到的值
也就是b[i]->f->sc += b[i]->sc;
#include <cstdio> #include <cstring> #include <iostream> using namespace std; #define N 500010 #define M 26 struct SamNode{ SamNode *son[26] , *f; int l , sc; }*root , *last , sam , *b ; int cnt , dp , num ; char s ; void init(){ root = last = &sam[cnt=0]; } void add(int x) { SamNode *p = &sam[++cnt] , *jp=last; p->l = jp->l+1; last = p; for( ; jp&&!jp->son[x] ; jp=jp->f) jp->son[x]=p; if(!jp) p->f = root; else{ if(jp->l+1 == jp->son[x]->l) p->f = jp->son[x]; else{ SamNode *r = &sam[++cnt] , *q = jp->son[x]; *r = *q; r->l = jp->l+1; q->f = p->f = r; for( ; jp && jp->son[x]==q ; jp=jp->f) jp->son[x]=r; } } } void solve() { init(); int len = strlen(s); for(int i=0 ; i<len ; i++) add(s[i]-'a'); //后面三个for循环相当于进行拓扑排序 for(int i=0 ; i<=cnt ; i++) num[sam[i].l]++; for(int i=1 ; i<=len ; i++) num[i]+=num[i-1]; for(int i=0 ; i<=cnt ; i++) b[--num[sam[i].l]] = &sam[i]; SamNode *cur = root; for(int i=0 ; i<len ; i++){ cur = cur->son[s[i]-'a']; cur->sc++; } for(int i=cnt ; i>0 ; i--){ int l = b[i]->l; dp[l] = max(dp[l] , b[i]->sc); b[i]->f->sc += b[i]->sc; } for(int i=len-1 ; i>=1 ; i--) dp[i]=max(dp[i] , dp[i+1]); for(int i=1 ; i<=len ; i++) printf("%d\n" , dp[i]); } int main() { // freopen("a.in" , "r" , stdin); scanf("%s" , s); solve(); return 0; }
相关文章推荐
- 谷歌搜索 site命令 指定网站搜索
- oracle12c ORA-28040: No matching authentication protocol错误
- SQL server 2005基本操作
- fedora实现多版本gcc共享
- Windows 7 64位安装Oracle XE(32位)数据库报错等解决方案
- 浙江大学PAT_甲级_1058. A+B in Hogwarts (20)
- leetcode--Binary Tree Right Side View
- sgu276:Andrew's Troubles(大大大水题)
- 创业公司如何实施敏捷开发
- iOS9和Xcode7
- (6/18)重学Standford_iOS7开发_控制器多态性、导航控制器、选项卡栏控制器_课程笔记
- Oracle重启与关闭 ORA-12528等
- 团队项目作业第八项:运行及总结
- Redis学习手册(List数据类型)
- [NOI2007]项链工厂(线段树)
- Centos上的屏幕保护
- Apache Rewrite重写模块(二):10个实例详细分析
- online judge 提交代码应该注意的事项
- jfinal的图片验证码实现
- Android 屏幕滑动事件