Codeforces 432D Prefixes and Suffixes (KMP、后缀数组)

题目链接: https://codeforces.com/contest/432/problem/D

题解L

做法一: KMP

显然next树上\(n\)的所有祖先都是答案,出现次数为next树子树大小。

做法二: 后缀数组

按照height分组,二分查找即可。

代码

KMP:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<utility>
using namespace std;

const int N = 1e5;
char a[N+3];
int nxt[N+3];
int sz[N+3];
vector<pair<int,int> > ans;
int n;

void KMP()
{
    nxt[0] = nxt[1] = 0;
    for(int i=2; i<=n; i++)
    {
        nxt[i] = nxt[i-1];
        while(nxt[i] && a[nxt[i]+1]!=a[i])
        {
            nxt[i] = nxt[nxt[i]];
        }
        if(a[nxt[i]+1]==a[i]) nxt[i]++;
    }
}

int main()
{
    scanf("%s",a+1); n = strlen(a+1);
    for(int i=1; i<n+1-i; i++) swap(a[i],a[n+1-i]);
    KMP();
    for(int i=1; i<=n; i++) sz[i] = 1;
    for(int i=n; i>=1; i--) sz[nxt[i]] += sz[i];
    for(int i=n; i>0; i=nxt[i])
    {
        ans.push_back(make_pair(i,sz[i]));
    }
    printf("%d\n",ans.size());
    for(int i=ans.size()-1; i>=0; i--) printf("%d %d\n",ans[i].first,ans[i].second);
    return 0;
}

原文地址:https://www.cnblogs.com/suncongbo/p/11043339.html

时间: 2024-10-28 20:24:33

Codeforces 432D Prefixes and Suffixes (KMP、后缀数组)的相关文章

Codeforces 432D Prefixes and Suffixes(KMP+dp)

题目连接:Codeforces 432D Prefixes and Suffixes 题目大意:给出一个字符串,求全部既是前缀串又是后缀串的字符串出现了几次. 解题思路:依据性质能够依据KMP算法求出全部的前后缀串,然后利用dp求解,dp[i]表示从1到i这个子串出现过的次数.转移方程dp[jump[i]]+=dp[i].随意一个dp[i]的初始状态应该是1. #include <cstdio> #include <cstring> const int N = 1e5+5; int

Codeforces 432D Prefixes and Suffixes

http://codeforces.com/problemset/problem/432/D 题目大意: 给出一个字符串,求有多少种长度的前缀和后缀相等,并且得到的这个子串在原字符串中出现的次数. 思路:预处理kmp,发现从n开始的next[n]一直往下都是合法的前缀后缀,先记录下来,然后从n往1dp,每次都是 dp[i]++,dp[next[i]]+=dp[i],这样转移之后再输出即可. 1 #include<cstdio> 2 #include<cmath> 3 #includ

codeforces432D Prefixes and Suffixes(kmp+dp)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud D. Prefixes and Suffixes You have a string s = s1s2...s|s|, where |s| is the length of string s, and si its i-th character. Let's introduce several definitions: A substring s[i..j] (1 ≤ i ≤ j

POJ-3450 Corporate Identity (KMP+后缀数组)

Description Beside other services, ACM helps companies to clearly state their "corporate identity", which includes company logo but also other signs, like trademarks. One of such companies is Internet Building Masters (IBM), which has recently a

POJ2406 Power Strings(KMP,后缀数组)

这题可以用后缀数组,KMP方法做 后缀数组做法开始想不出来,看的题解,方法是枚举串长len的约数k,看lcp(suffix(0), suffix(k))的长度是否为n- k ,若为真则len / k即为结果. 若lcp(suffix(0), suffix(k))的长度为n- k,则将串每k位分成一段,则第1段与第2段可匹配,又可推得第2段与第3段可匹配……一直递归下去,可知每k位都是相同的,画图可看出匹配过程类似于蛇形. 用倍增算法超时,用dc3算法2.5秒勉强过. #include<cstdi

POJ 2406 KMP/后缀数组

题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就能求出循环次数. #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<str

ZOJ1905Power Strings (KMP||后缀数组+RMQ求循环节)

Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defin

luogu 2463 [SDOI2008]Sandy的卡片 kmp || 后缀数组 n个串的最长公共子串

题目链接 Description 给出\(n\)个序列.找出这\(n\)个序列的最长相同子串. 在这里,相同定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串. 思路 参考:hzwer. 法一:kmp 在第一个串中枚举答案串的开头位置,与其余\(n-1\)个串做\(kmp\). 法二:后缀数组 将\(n\)个串拼接起来.二分答案\(len\),将\(height\)分组,\(check\)是否有一组个数\(\geq len\)且落在\(n\)个不同的串中. 注意:\(n\)个串

【HDU - 5442】Favorite Donut 【最大表示法+KMP/后缀数组】

题意 给出一个长度为n的环状由小写字母组成的序列,请找出从何处断开,顺时针还是逆时针,使得字典序最大.如果两个字符串的字典序一样大,那么它会选择下下标最小的那个.如果某个点顺时针逆时针产生的字典序大小相同,那么优先选择顺时针的. 这个题用最大表示法+KMP很容易解决.因为最大表示法找到的是下表最小的那个字典序最大的字符串,所以正向的时候最大表示法找出来的就直接是答案,关键是逆时针的时候.我们将字符串翻转以后用最大表示法找到那个字符串s2,然后用KMP算法在翻转*2后的串中找出最后面的那个s2,这