zoukankan      html  css  js  c++  java
  • Codeforce432D Prefixes and Suffixes

    题意:输入一个字符串,问前缀和后缀相同的字符串长度以及这些字符串出现的次数

    题解:

    方法1:首先计算前缀和后缀相等的字符串,可以发现这就是KMP中next数组的定义while(next[t]) t = ne[t]可以找到所有满足条件的串

    这时候只要算每个字符串出现的次数,设dp[i]为前缀在串中出现的次数,那么dp[next[i]] += dp[i]这里很好理解,每一个i都会对next[i]作出贡献,倒着dp,初始化为1

    方法2:这道题也可以用后缀数组来做,后缀数组计算出height数组,那么只要计算所有后缀和整个串的最长公共前缀,等于后缀长度的就是满足条件的串

    最后计算串出现的次数,可以在计算最长公共前缀的时候记录在数组,最后算一个后缀和就可以

    这里用方法1

    #include <bits/stdc++.h>
    #define maxn 101000
    #define INF 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    char s[maxn];
    int ne[maxn], dp[maxn];
    vector<pair<int ,int > >v;
    void kmp_init(char *x,int l,int *next){
        int i = 0, j = next[0] = -1;
        while(i<l){
            while(j!=-1&&x[i]!=x[j]) j = next[j];
            next[++i] = ++j;
        }
    }
    int main(){
        scanf("%s", s);
        int l = strlen(s);
        kmp_init(s, l, ne);
        for(int i=l;i>=1;i--){
            dp[i]++;
            dp[ne[i]] += dp[i];
        }
        for(int i=1;i<=l;i++) cout<<ne[i]<<" ";cout<<endl;
        int t = l;
        while(t){
            v.push_back(make_pair(t, dp[t]));
            t = ne[t];
        }
        sort(v.begin(), v.end());
        cout<<v.size()<<endl;
        for(auto j:v) cout<<j.first<<" "<<j.second<<endl;
        return 0;
    }
  • 相关阅读:
    Asp.net MVC3 Razor语法小记
    asp.net4的webform使用路由
    判断数据库中要创建的存储过程、函数等是否已经存在
    visual studio 解决方案版本互转
    sql语句创建表的时候加表注释和列注释
    Jquery在指定元素内查找元素(相对定位)
    .net便利的小方法
    sqlserver2008秘钥
    jquery星级评定效果(原创)
    清除GridView自带样式
  • 原文地址:https://www.cnblogs.com/Noevon/p/8331106.html
Copyright © 2011-2022 走看看