• Codeforces 432D Prefixes and Suffixes:KMP + dp


    题目链接:http://codeforces.com/problemset/problem/432/D

    题意:

      给你一个字符串s,让你找出所有既是前缀又是后缀的子串,并输出它们分别出现了多少次。

    题解:

      先对原串求一次nex数组。

      然后枚举位置i:

        sub(k)表示前缀s[0 to k]

        dp[i]表示sub(i)在原串s中的出现次数

        假设nex[i] = a, nex[a] = b, nex[b] = c ... nex[z] = -1

        则sub(a), sub(b), sub(c)...sub(z)均以s[i]结尾,dp[a...z]均+1。

      然而一个一个加会T...

      

      所以:

        初始时所有的 dp = 1

        每次:if(nex[i] != -1) dp[nex[i]] += dp[i]

        一路传递下去就好。

      

      最后从nex[len-1]开始往前跳nex。

      对于每次跳到的nex,sub(nex)一定也是s的后缀。

      此时输出它的出现次数dp[nex]。

      另外因为要顺着输出,而nex是倒着跳的,所以先存到stack里再输出。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <stack>
     5 #define MAX_N 100005
     6 
     7 using namespace std;
     8 
     9 int n;
    10 int dp[MAX_N];
    11 int nex[MAX_N];
    12 char s[MAX_N];
    13 
    14 void cal_nex(char *p,int len)
    15 {
    16     nex[0]=-1;
    17     int k=-1;
    18     for(int i=1;i<len;i++)
    19     {
    20         while(k>-1 && p[i]!=p[k+1]) k=nex[k];
    21         if(p[i]==p[k+1]) k++;
    22         nex[i]=k;
    23     }
    24 }
    25 
    26 int main()
    27 {
    28     scanf("%s",s);
    29     n=strlen(s);
    30     cal_nex(s,n);
    31     for(int i=0;i<n;i++) dp[i]=1;
    32     for(int i=n-1;i>=0;i--)
    33     {
    34         if(nex[i]!=-1) dp[nex[i]]+=dp[i];
    35     }
    36     stack<int> stk;
    37     int p=n-1;
    38     while(p!=-1)
    39     {
    40         stk.push(p);
    41         p=nex[p];
    42     }
    43     cout<<stk.size()<<endl;
    44     while(!stk.empty())
    45     {
    46         int now=stk.top();
    47         stk.pop();
    48         cout<<now+1<<" "<<dp[now]<<endl;
    49     }
    50 }
  • 相关阅读:
    bzoj2599
    在Linux下配置jdk的环境变量
    liunx 命令大全
    Liunx下如何使用kettle
    Liunx 解压篇
    Linux下安装MySQL-5.7
    Linux文件权限查看及修改命令chmod,chown
    spring 驱动模式
    Struts2标签之Checkbox
    spring 注解的优点缺点
  • 原文地址:https://www.cnblogs.com/Leohh/p/8185474.html
Copyright © 2020-2023  润新知