CF271D_Good Substrings

给一个原串,以及那些字符是坏的,现在问你可以从原串中取出多少个不同子串,使得其所含的坏字符的个数不超过一个定数。

这个题目网上有各种各样的解法。如hash,tire。

我说一下我的解法。

解法一:后缀自动机dp。f[][]保存到达某个状态,前面已经有的坏字符的个数的时候的字符串数量。这样按照拓扑序列一直递推下去就可以了。时间复杂度为O(N2)。

解法二:后缀自动机,预处理。对于字符串,每个位置保存它可以最前走到那个位置。然后,在自动机上增加信息,保存位置。然后直接按照距离判断就可以了。对于每个节点,直接缩小范围,更新答案。时间复杂度为O(N)。

召唤代码君:

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 3555
using namespace std;

char real[26],s[maxn];
int next[maxn][26],pre[maxn],step[maxn];
int N,last,n,L;
int p,q,np,nq,ans=0;
int f[maxn],tag[maxn],sum[maxn];

void insert(int x,int ggg)
{
	p=last,np=++N,step[np]=step[p]+1,last=np,tag[np]=ggg;
	for (; p!=-1 && next[p][x]==0; p=pre[p]) next[p][x]=np;
	if (p==-1) return;
	q=next[p][x];
	if (step[q]==step[p]+1) { pre[np]=q; return ; }
	nq=++N,step[nq]=step[p]+1,pre[nq]=pre[q],tag[nq]=ggg;
	for (int i=0; i<26; i++) next[nq][i]=next[q][i];
	pre[np]=pre[q]=nq;
	for (; p!=-1 && next[p][x]==q; p=pre[p]) next[p][x]=nq;
}

int main()
{
	scanf("%s",s+1);
	scanf("%s",real);
	scanf("%d",&n);
	pre[0]=-1;
	L=strlen(s+1);
	for (int i=1; s[i]; i++) insert(s[i]-‘a‘,i);
	sum[0]=0;
	for (int i=1; i<=L; i++)
	{
		sum[i]=sum[i-1];
		if (real[s[i]-‘a‘]==‘0‘) sum[i]++;
	}

	f[L+1]=L+1;
	for (int i=L; i>=1; i--)
	{
		int k=min(f[i+1],i+1);
		for ( ;k>1 && sum[i]-sum[k-2]<=n; k--) ;
		f[i]=k;
	}

	for (int i=1; i<=N; i++)
	{
		int l=tag[i]-step[i]+1,r=tag[i]-step[pre[i]];
		if (f[tag[i]]>l) l=f[tag[i]];
		if (l<=r) ans+=r-l+1;
	}
	printf("%d\n",ans);
	return 0;
}

  

CF271D_Good Substrings

时间: 2024-10-05 12:43:32

CF271D_Good Substrings的相关文章

[Leetcode] DP-- 467. Unique Substrings in Wraparound String

Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz", so s will look like this: "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....". Now we have another string p. Your job is to find

uva 10829 - L-Gap Substrings(后缀数组)

题目链接:uva 10829 - L-Gap Substrings 题目大意:给定一个字符串,问有多少字符串满足UVU的形式,要求U非空,V的长度为g. 解题思路:对字符串的正序和逆序构建后缀数组,然后枚举U的长度l,每次以长度l分区间,在l和l+d+g所在的两个区间上确定U的最大长度. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using nam

[LeetCode] Unique Substrings in Wraparound String 封装字符串中的独特子字符串

Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz", so s will look like this: "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....". Now we have another string p. Your job is to find

POJ 3415 Common Substrings (求长度不小于k的公共子串的个数)

Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10002   Accepted: 3302 Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S,

字符串(后缀数组):POJ 3415 Common Substrings

Common Substrings Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S, a set of triples (i, j, k): S = {(i, j, k) | k≥K, A(i, k)=B(j, k)}. You are to give

SPOJ 题目694 Distinct Substrings(后缀数组,求不同的子串个数)

DISUBSTR - Distinct Substrings no tags Given a string, we need to find the total number of its distinct substrings. Input T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 1000 Output For each test case output

解题报告 之 POJ1226 Substrings

解题报告 之 POJ1226 Substrings Description You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings. Input The first li

SPOJ 705 New Distinct Substrings

New Distinct Substrings Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Original ID: SUBST164-bit integer IO format: %lld      Java class name: Main Given a string, we need to find the total number of its distinct subst

CodeForces 451D Count Good Substrings

哎,最近都在做图论,没有练DP,现在一遇到DP就不会了= = 因为有合并这个操作,所以只要是首位相同的字符串肯定是能够构成good串的,那么只要统计在奇数位上出现的0,1的个数和偶数位数,随便递推一下就出来了 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #i