zoukankan      html  css  js  c++  java
  • 51nod 1277字符串中的最大值(拓展kmp)

    题意:
    一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd。
    给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值。
     
    题解:
    我们前缀匹配的位置个数随长度是递减的(即长度越长,位置越少)。
    用拓展kmp对自身求Next数组
    我们就知道了每个前缀能匹配的最大后缀的那些位置
    然后按照匹配长度倒序相加即是匹配的位置个数。
     
    #include <iostream>
    #include <cstring>
    using namespace std;
    const int maxn = 1e6 + 100;
    char S[maxn];
    int Next[maxn], extend[maxn];
    void GetNext(char *T, int *Next){
        int len = strlen(T);
        Next[0] = len;
        int a, p;
        for(int i = 1, j = -1; i < len; i++, j--){
           if(j < 0 || i + Next[i-a] >= p){
                if(j < 0) p = i, j = 0;
                while(p < len && T[p] == T[j])
                    p++, j++;
                Next[i] = j;
                a = i;
           } else Next[i] = Next[i-a];
        }
    }
    void GetExtend(char *S, char *T, int *extend, int *Next){
        GetNext(T, Next);
        int a, p;
        int slen = strlen(S), tlen = strlen(T);
        for(int i = 0, j = -1; i < slen; i++, j--){
            if(j < 0 || i + Next[i-a] >= p){
                if(j < 0) p = i, j = 0;
                while(p < slen && j < tlen && S[p] == T[j]) p++, j++;
                extend[i] = j;
                a = i;
            } else extend[i] = Next[i-a];
        }
    }
    int Num[maxn];
    int main(){
        cin>>S;
        int len = strlen(S);
        GetNext(S, Next);
        for(int i = 0; i < len; i++) Num[Next[i]]++;
        long long ans = 0, n = 0;
        for(int i = len; i >= 1; i--){
            n += Num[i];
            ans = max(ans, n*i);
        }
        cout<<ans<<endl;
    }
     
     
  • 相关阅读:
    MongoDB的下载与安装
    Oracle PL/SQL 编程手册(SQL大全)
    内部类、异常、其他
    异常(补充)
    final、抽象类、接口、多态、
    改变JVM中的参数以提高Eclipse的运行速度
    Java中的三目运算符 详解
    Java中的Stringbuffer类解析
    Staitic(静态) 相关知识点介绍
    Java反射
  • 原文地址:https://www.cnblogs.com/Saurus/p/7637707.html
Copyright © 2011-2022 走看看