SPOJ 8222 Substrings 后缀自动机入门
来源:互联网 发布:radium for mac 编辑:程序博客网 时间:2024/06/11 05:36
NSUBSTR - Substrings
You 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
Submit solution!
题意:求一个字符串当中,长度为1,2..len的子串最多出现多少次。
根据字符串构造后缀自动机。
我们在每个节点上已经得到的最长的长度maxlen,则只要求出这个点的|right|,去更新ans[1...maxlen]就好了。实际上,只需要更新ans[maxlen],再O(n)的从长度较长的答案向长度小的答案更新。
而对于每个点的|right|,我们先把原串在自动机上跑一遍,把跑到的节点都设为1,其余设为0.之后,根据拓扑排序的关系从后向前推,即可获得每个点的|right|值。
#include <cstdio>#include <iostream>#include <string.h>#define mem0(a) memset(a,0,sizeof(a))#define meminf(a) memset(a,0x3f,sizeof(a))using namespace std;typedef long long ll;typedef long double ld;typedef double db;const int maxn=250005,maxk=26,inf=0x3f3f3f3f; const ll llinf=0x3f3f3f3f3f3f3f3f;int dp[maxn*2],f[maxn*2],w[maxn*2],r[maxn*2];char s[maxn];class SAM { public: void init() { num=last=0; a[0].len=0;a[0].fa=-1; for (int i=0;i<maxk;i++) a[0].son[i]=-1; } void update (int c) { int now=++num,p; a[now].len=a[last].len+1; memset(a[now].son,-1,sizeof(a[now].son)); for (p=last;p!=-1&&a[p].son[c]==-1;p=a[p].fa) a[p].son[c]=now; if (p==-1) a[now].fa=0; else { int q=a[p].son[c]; if (a[p].len+1==a[q].len) { a[now].fa=q; } else { int ne=++num; a[ne].len=a[p].len+1; memcpy(a[ne].son,a[q].son,sizeof(a[q].son)); a[ne].fa=a[q].fa; for (;p!=-1&&a[p].son[c]==q;p=a[p].fa) a[p].son[c]=ne; a[q].fa=a[now].fa=ne; } } last=now; } int getson(int n,int c) { return a[n].son[c]; } int getnum() { return num; } int getfa(int n) { return a[n].fa; } int getlen(int n) { return a[n].len; } private: int num,last; struct node{ int len,fa; int son[maxk]; } a[maxn*2]; }; SAM sa; int main() {int n,m,len,i,j;scanf("%s",s);len=strlen(s);sa.init();for (i=0;i<len;i++) {sa.update(s[i]-'a');}mem0(dp);int now=0;m=sa.getnum();/*for(i=0;i<=m;i++) {cout << sa.getfa(i) << endl;}*/for (i=0;i<len;i++) {now=sa.getson(now,s[i]-'a');dp[now]++;} mem0(w); for(i=0;i<=m;i++) w[sa.getlen(i)]++; for(i=0;i<=len;i++) w[i]+=w[i-1]; for(i=m;i>=0;i--) r[--w[sa.getlen(i)]]=i; for (i=m;i>0;i--) { int to=sa.getfa(r[i]); if (to!=-1) dp[to]+=dp[r[i]]; } mem0(f); for (i=1;i<=m;i++) { int p=sa.getlen(i);f[p]=max(f[p],dp[i]);}for (i=len-1;i>=1;i--) f[i]=max(f[i],f[i+1]);for (i=1;i<=len;i++) printf("%d\n",f[i]);return 0;}
阅读全文
0 0
- SPOJ 8222 Substrings 后缀自动机入门
- spoj 8222 Substrings (后缀自动机)
- spoj 8222 substrings 【后缀自动机】
- SPOJ Substrings --后缀自动机
- spoj Substrings【后缀自动机】
- spoj 8222 Substrings(NSUBSTR),后缀自动机
- spoj 8222 Substrings (后缀自动机+dp)
- spoj 8222 Substrings(后缀自动机)
- SPOJ 8222 NSUBSTR - Substrings (后缀自动机)
- [后缀自动机 模板题] SPOJ 8222 Substrings
- SPOJ NSUBSTR Substrings 后缀自动机
- SPOJ - NSUBSTR Substrings 后缀自动机
- SPOJ 8222. Substrings(后缀自动机模板)
- SPOJ 8222 [后缀自动机]
- SPOJ 题目 8222 NSUBSTR - Substrings(后缀自动机+DP求子串出现最大次数)
- 后缀自动机小结 (spoj 8222)
- SPOJ 8222 NSUBSTR 后缀自动机
- Sphere 8222 Substrings【后缀自动机+dp】
- ThreadLocal完全解析
- 读书笔记-《Java NIO》:第三章 通道(5)
- Oracle-1-概念篇
- 【论文笔记】Neural Relation Extraction with Multi-lingual Attention
- 实验二 Linux用户管理
- SPOJ 8222 Substrings 后缀自动机入门
- RPC 远程过程调用协议
- 【学习笔记】Git
- FreeMarker(四)流程控制语句
- Android下的Touch事件分发
- HDOJ 1018 Big Number (大数位数)
- 利用keras框架cnn+ctc_loss识别不定长字符图片
- 解决上位词问题
- 连续总结第7天