spoj8222

地址:

题目:

NSUBSTR - Substrings

no tags

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:32211

思路:

  先求出每个状态的endpos集合大小,用cnt记录,用cnt[s]去更新f[len[s]],再用f[i+1]去更新f[i].

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 char ss[300004];
 6 int ans,f[300001<<1];
 7
 8 struct SAM
 9 {
10     static const int MAXN = 300001<<1;//大小为字符串长度两倍
11     static const int LetterSize = 26;
12
13     int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
14     int sum[MAXN], tp[MAXN], cnt[MAXN]; //sum,tp用于拓扑排序,tp为排序后的数组
15
16     void init( void)
17     {
18         last = tot = 1;
19         len[1] = 0;
20         memset(ch,0,sizeof ch);
21         memset(fa,0,sizeof fa);
22         memset(cnt,0,sizeof cnt);
23     }
24
25     void add( int x)
26     {
27         int p = last, np = last = ++tot;
28         len[np] = len[p] + 1, cnt[last] = 1;
29         while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
30         if( p == 0)
31             fa[np] = 1;
32         else
33         {
34             int q = ch[p][x];
35             if( len[q] == len[p] + 1)
36                 fa[np] = q;
37             else
38             {
39                 int nq = ++tot;
40                 memcpy( ch[nq], ch[q], sizeof ch[q]);
41                 len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
42                 while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
43             }
44         }
45     }
46
47     void toposort( void)
48     {
49         for(int i = 1; i <= len[last]; i++)   sum[i] = 0;
50         for(int i = 1; i <= tot; i++)   sum[len[i]]++;
51         for(int i = 1; i <= len[last]; i++)   sum[i] += sum[i-1];
52         for(int i = 1; i <= tot; i++)   tp[sum[len[i]]--] = i;
53         for(int i = tot; i; i--)   cnt[fa[tp[i]]] += cnt[tp[i]];
54     }
55 } sam;
56
57
58 int main(void)
59 {
60     //freopen("in.acm","r",stdin);
61     sam.init();
62     scanf("%s",ss);
63     for(int i=0,len=strlen(ss);i<len;i++)  sam.add(ss[i]-‘a‘);
64     sam.toposort();
65     for(int i=1;i<=sam.tot;i++)    f[sam.len[i]]=max(f[sam.len[i]],sam.cnt[i]);
66     for(int i=sam.len[sam.last];i;i--) f[i]=max(f[i],f[i+1]);
67     for(int i=1;i<=sam.len[sam.last];i++)   printf("%d\n",f[i]);
68     return 0;
69 }
时间: 2024-07-31 03:41:37

spoj8222的相关文章

【spoj8222】 Substrings

http://www.spoj.com/problems/NSUBSTR/ (题目链接) 题意 给出一个字符串S,令${F(x)}$表示S的所有长度为x的子串出现次数的最大值.求${F(1)......F(length(S))}$ Solution 后缀自动机例题,下面写几点自己认为理解后缀自动机的重点. 后缀自动机相对于后缀树就是将Right集合相同的子串合用一个节点来表示.每一个节点代表一个状态S,这个状态可能包含很多长度区间连续的子串,这些子串的右端点固定,它们的Right集合相同. 往上

SPOJ8222 Substrings( 后缀自动机 + dp )

题目大意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.F(1)..F(Length(S)) 建出SAM, 然后求出Right, 求Right可以按拓扑序dp..Right就是某个点到结束状态的路径数, parent树上last的那一条链都是结束状态...然后用Right去更新答案.. spoj卡常数..一开始用DFS就炸了, 改用BFS就A了.. (贴一下丽洁姐的题解: 我们构造S的SAM,那么对于一个节点s,它的长度范围是[Min(s),Max(s)],同时他的出

[SPOJ8222]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

[SPOJ8222]NSUBSTR - Substrings 后缀自动机

1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int sz=0,la,rt; 6 int ch[500010][26],l[500010],fa[500010]; 7 void Extend(int c){ 8 int end=++sz,tmp=la; 9 l[end]=l[tmp]+1; 10 while(tmp&&!ch[tm

【spoj8222】Substrings

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #define maxn 500005 7 #define maxm 250005 8 using namespace std; 9 10 int n,tot,root,last,f[maxm],fa[maxn],son[maxn][2

SPOJ8222/NSUBSTR:Substrings——题解

https://www.luogu.org/problemnew/show/SP8222#sub http://www.spoj.com/problems/NSUBSTR/ 翻译来自洛谷. 你得到一个字符串,最多由25万个小写拉丁字母组成.我们将 F(x)定义为某些长度X的字符串在s中出现的最大次数,例如字符串'ababaf'- F(x),因为有一个字符串'ABA'出现两次.你的任务是输出 F(x)每一个I,以使1<=i<=|S|. water! 后缀自动机后对l排个序,对每个l更新其ans就

SPOJ8222 NSUBSTR - Substrings 后缀自动机_动态规划

讲起来不是特别好讲.总之,如果 $dp[i+1]>=dp[i]$,故$dp[i]=max(dp[i],dp[i+1])$ Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) freopen(s".in","r",stdin) #define maxn 2000000 #define N 30 #define ll l

【SPOJ8222】Substrings (后缀自动机)

题意: 给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值. 求F(1)..F(Length(S)) Length(S) <= 250000 思路:板子中st[x]定义为root到x的最多步数,可以用来更新所有长度为[1..st[x]]的答案 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef u

poj 3415

Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7605   Accepted: 2524 Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S, a