51nod 1277 字符串中的最大值

题目链接

51nod 1277 字符串中的最大值

题解

对于单串,考虑多串的fail树,发现next数组的关系形成树形结构
建出next树,对于每一个前缀,他出现的次数就是他子树的大小

代码

#include<cstdio>
#include<cstring>
#include<algorithm>  

inline int read() {
    int x = 0,f = 1;
    char c = getchar();
    while(c < '0' || c > '9')c = getchar();
    while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
    return x * f;
} 

const int maxn = 100007;
struct node  {
    int v,next;
} edge[maxn << 1];
int num = 0,head[maxn];
inline void add_edge(int u,int v) {
    edge[++ num].v = v; edge[num].next = head[u];head[u] = num;
}
long long siz[maxn];
char s[maxn];
int next[maxn];
int len = 0;
void getnext() {
    next[0] = -1;
    for(int j = 0,i = 2;i <= len;++ i) {
        for(;s[i] != s[j + 1] && j > 0;j = next[j]);
        if(s[i] == s[j + 1]) { next[i] = j + 1,++ j; add_edge(j,i); }
    }
}
long long ans = 0;
void dfs(int x) {
    siz[x] = 1;
    for(int i = head[x];i;i = edge[i].next) {
        dfs(edge[i].v);
        siz[x] += siz[edge[i].v];
    }
    ans = std::max(ans, (long long) x * siz[x]);
}
int main() {
    scanf("%s",s + 1);
    len = strlen(s + 1);
    getnext();
    for(int i = 1;i <= len;++ i) if(!next[i]) dfs(i);
    printf("%lld\n",ans);
    return 0;
} 

原文地址:https://www.cnblogs.com/sssy/p/9520680.html

时间: 2024-10-07 22:19:48

51nod 1277 字符串中的最大值的相关文章

51Nod 1277 字符串中的最大值(KMP,裸题)

1277 字符串中的最大值 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd. 给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值. 例如:S = "abababa" 所有的前缀如下: "a", 长度与出现次数的乘积 1 * 4 = 4, "ab",长度与出

51Nod 1277 字符串中的最大值 ( KMP &amp;&amp; DP )

题意 : 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd.给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值.例如:S = "abababa" 所有的前缀如下: "a", 长度与出现次数的乘积 1 * 4 = 4, "ab",长度与出现次数的乘积 2 * 3 = 6, "aba", 长度与出现次数的乘积 3 * 3 = 9, "abab&

51nod 1277 字符串中的最大值(KMP算法)

分析: KMP算法:参考http://www.cnblogs.com/c-cloud/p/3224788.html,是一个线性处理字符串匹配问题的算法 在这里利用到next数组,记t[i]为长度为i的前缀出现的次数,显然t[n]=1.next[i]即为子串[0,i]的后缀与前缀重复的最长长度,因此可以统计一下next[i]的取值的个数,然后较长的前缀出现一次代表较短的前缀也一次,递推一下即可,复杂度为O(n). 1 #include<iostream> 2 #include<cstrin

[2013百度软件研发笔试题] 求字符串中连续出现同样字符的最大值

题目完整描写叙述为:用递归的方式实现一个求字符串中连续出现同样字符的最大值.如aaabbcc,连续出现a的最大值为3,abbc,连续出现字符最大的值为2. 下面是我想出来的方法: #include <iostream> using namespace std; #define MAX(a, b) (a) > (b) ? (a) : (b) int Get(char *s, int n, int m)  //字符指针, 当前最长串, max最长串 {     if(*(s+1) == '\

[2013百度软件研发笔试题] 求字符串中连续出现相同字符的最大值

题目完整描述为:用递归的方式实现一个求字符串中连续出现相同字符的最大值,如aaabbcc,连续出现a的最大值为3,abbc,连续出现字符最大的值为2. 以下是我想出来的方法: #include <iostream> using namespace std; #define MAX(a, b) (a) > (b) ? (a) : (b) int Get(char *s, int n, int m)  //字符指针, 当前最长串, max最长串 {     if(*(s+1) == '\0'

数据结构与算法-字符串输出数组中的最大值

输出数组a中的最大值及其下标 #include<stdio.h> #define N 5 int main() { int a[N],i,max,t; for(i=0;i<N;i++) scanf("%d",&a[i]); max=a[0]; //把数组的第一个数赋值给max,此时对应的下标为0 t=0; for(i=1;i<N;i++) //从数组的第二个数开始判断,max是否是最大值 if(max<a[i]){ //不是最大值,就把该值赋值给m

51nod 1277 KMP 前缀出现次数

51NOD 1277:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1277 跟HDU 6153还挺像的:http://www.cnblogs.com/Egoist-/p/7435573.html 相比与上面那个题,这个还要相对简单一些,只需要处理模式串自己就好了. 一开始写麻烦了,直接套了HDU6153的代码,后来发现--他就是个模式串本身的匹配,我干嘛弄那么麻烦Orz 题意:找前缀长度*出现次数的最大值,长度好说,

[LeetCode] Unique Substrings in Wraparound String 封装字符串中的独特子字符串

Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz", so s will look like this: "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....". Now we have another string p. Your job is to find

Java 求字符串中出现频率最高字符

前段时间接触的这个题目,大体理解了,还有些小地方仍待进一步品味,暂且记下. import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /* * 查找字符串中出现频率最高的字符 * * 主要思路:先将字符