SPOJ NSUBSTR - Substrings
2015-08-14 18:53
344 查看
NSUBSTR - Substrings
no tagsYou are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string 'ababa' F(3) will be 2 because there is a string 'aba' that occurs twice. Your task is to output F(i) for every i so that 1<=i<=|S|.Input
String S consists of at most 250000 lowercase latin letters.Output
Output |S| lines. On the i-th line output F(i).Example
Input: ababa Output: 3 2 2 1 1 解题:SAM求出现次数最多的且长度为i的串的次数
#include <bits/stdc++.h> using namespace std; const int maxn = 351000; struct SAM { struct node { int son[26],f,len; void init() { f = -1; len = 0; memset(son,-1,sizeof son); } } s[maxn<<1]; int tot,last; void init() { tot = last = 0; s[tot++].init(); } int newnode() { s[tot].init(); return tot++; } void extend(int c){ int np = newnode(),p = last; s[np].len = s[p].len + 1; while(p != -1 && s[p].son[c] == -1){ s[p].son[c] = np; p = s[p].f; } if(p == -1) s[np].f = 0; else{ int q = s[p].son[c]; if(s[p].len + 1 == s[q].len) s[np].f = q; else{ int nq = newnode(); s[nq] = s[q]; s[nq].len = s[p].len + 1; s[q].f = s[np].f = nq; while(p != -1 && s[p].son[c] == q){ s[p].son[c] = nq; p = s[p].f; } } } last = np; } } sam; char str[maxn]; int c[maxn<<1],ans[maxn],rk[maxn<<1],w[maxn]; int main() { while(~scanf("%s",str)) { sam.init(); int len = strlen(str); for(int i = 0; i < len; ++i) sam.extend(str[i] - 'a'); memset(ans,0,sizeof ans); memset(c,0,sizeof c); memset(w,0,sizeof w); for(int i = 1; i < sam.tot; ++i) ++w[sam.s[i].len]; for(int i = 1; i <= len; ++i) w[i] += w[i-1]; for(int i = sam.tot-1; i > 0; --i) rk[w[sam.s[i].len]--] = i; for(int i = 0, p = 0; i < len; ++i) ++c[p = sam.s[p].son[str[i]-'a']]; for(int i = sam.tot-1; i > 0; --i) { ans[sam.s[rk[i]].len] = max(ans[sam.s[rk[i]].len],c[rk[i]]); if(sam.s[rk[i]].f > 0) c[sam.s[rk[i]].f] += c[rk[i]]; } for(int i = 1; i <= len; ++i) printf("%d\n",ans[i]); } return 0; }View Code
相关文章推荐
- Boostrap入门+样式学习--壹--
- 九度 Online Judge 算法 刷题 题目1057:众数
- 栈的应用--简单计算器---加减乘除
- ios Masonary的使用
- arcengine 文件夹连接
- 学习笔记-----Android的View绘制过程
- 杭电3342Legal or Not
- iOS arc与非arc混编 以及设置UINavigationBar的高度
- POJ 1061 青蛙的约会(扩展欧几里得算法)
- Java高级应用(一个)-文件夹监控服务
- HDU 3377 插头dp
- No package mysql-server available.
- Nginx模块开发(5)————开发简单的HTTP过滤模块
- MySQL5.6安装步骤(windows7/8_64位)
- Ubuntu下git使用
- APK 代码混淆
- poj2367
- 一致性哈希算法及其在分布式系统中的应用
- java:关于字符编码的试题
- 图论500题