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 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 char s[200005];
 7 int n,p[200005],c[200005],dp[200005];
 8 int read(){
 9     int t=0,f=1;char ch=getchar();
10     while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-1;ch=getchar();}
11     while (‘0‘<=ch&&ch<=‘9‘){t=t*10+ch-‘0‘;ch=getchar();}
12     return t*f;
13 }
14 int main(){
15     scanf("%s",s+1);
16     n=strlen(s+1);
17     p[1]=0;int j=0;
18     for (int i=2;i<=n;i++){
19         while (j>0&&s[j+1]!=s[i]) j=p[j];
20         if (s[j+1]==s[i]) j++;
21         p[i]=j;
22     }
23     int tot=0;
24     for (int i=p[n];i;i=p[i]){
25         c[++tot]=i;
26     }
27     for (int i=n;i;i--){
28         dp[i]++;
29         dp[p[i]]+=dp[i];
30     }
31     printf("%d\n",tot+1);
32     for (int i=tot;i>=1;i--){
33         printf("%d %d\n",c[i],dp[c[i]]);
34     }
35     printf("%d 1\n",n);
36     return 0;
37 }
时间: 2024-10-11 22:35:32

Codeforces 432D Prefixes and Suffixes的相关文章

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 (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&g

codeforces 432D D . Prefixes and Suffixes(后缀数组)

题目链接: codeforces 432D 题目大意: 给出一个字符串,求有多少种长度的前缀和后缀相等,并且得到的这个子串在原字符串中出现的次数. 题目分析: 首先利用后缀数组处理出sa[i]代表排名第i位的后缀的起始位置 处理出rank[i]代表第i个位置起始的后缀的rank 处理出height[i]代表排名第i位的和排名i-1位的公共前缀的长度. 那么我们要找后缀和前缀相等的就是找到rank[0],然后按照排名,向前向后遍历,任意两个后缀的公共前缀就是他们[i,j]区间内所有height的最

codeforces Round 246 D. Prefixes and Suffixes (后缀数组 || KMP)

题目大意: 求一个子串,子串既是前缀又是后缀. 然后再求出它在整个串中出现的次数. 思路分析: 可以很容易想到如何判断一个串既是前缀又是后缀. 只需要它与 sa[0] 的lcp 等于 整个串的长度减去它的 sa 值. 然后接下来的工作是判断出现了 多少次. 首先我们想到,如果这个子串是目标前后缀. 那么出现过它的子串在sa 中的下标一定比这个串大. 因为它已经是最简的了. 然后可以直接二分求出他出现了多少次. #include <iostream> #include <cstdio>

CodeForces Round #527 (Div3) C. Prefixes and Suffixes

http://codeforces.com/contest/1092/problem/C Ivan wants to play a game with you. He picked some string ss of length nn consisting only of lowercase Latin letters. You don't know this string. Ivan has informed you about all its improper prefixes and s

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

CF432D Prefixes and Suffixes

CF432D Prefixes and Suffixes 题意 给你一个长度为n的长字符串,"完美子串"既是它的前缀也是它的后缀,求"完美子串"的个数且统计这些子串的在长字符串中出现的次数 分析 求出nex数组 , 在求出每个前缀出现的次数 , 从nex[n] 往下走就行了 其实这道题是 , KMP 求每个前缀出现次数的模板题 求前缀出现次数的写法 for(int i = 1 ; i <= n ; ++i) num[i]++; for(int i = n ;

CodeForces 368B Sereja and Suffixes

Sereja and Suffixes Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 368B64-bit integer IO format: %I64d      Java class name: (Any) Sereja has an array a, consisting of n integers a1, a2, ..., an. The

BZOJ3483 : SGU505 Prefixes and suffixes(询问在线版)

将每个串正着插入Trie A中,倒着插入Trie B中. 并求出每个串在A,B中的dfs序. 每次查询等价于查询在A中dfs序在[la,ra]之间,在B中dfs序在[lb,rb]之间的串的个数,用主席树维护即可. #include<cstdio> const int S=2000010,N=2010,M=N*22; char s[S],ch; int n,m,i,j,k,posa[N],posb[N],g[S],v[N],nxt[N],ed,la,lb,ra,rb,ans; inline vo