CF1335E Three Blocks Palindrome

Posted suxxsfe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1335E Three Blocks Palindrome相关的知识,希望对你有一定的参考价值。

就是我这个菜鸡,赛时写出了 E2 的做法,但是算错复杂度,导致以为自己的做法只能AC E1,就没交到 E2 上,然后赛后秒A.....

题意

定义一种字串为形如:([underbrace{a, a, dots, a}_{x}, underbrace{b, b, dots, b}_{y}, underbrace{a, a, dots, a}_{x}])

问你在给定的字串中,符合这种要求的最大子序列(可以不连续)的长度
给出数列长度 (nle 2cdot 10^5),数列中每个数 (a_ile 200)


考虑暴力枚举 (a),然后对于每一个 (a),枚举 (x),也就是两边的 (a) 的 个数
用两个 vector,分别记录从前和从后数,第 (x)(a) 的位置
然后一直枚举到第 (lfloordfrac{ ext{a出现的次数}}{2} floor)
此时,再暴力枚举 (b),记录一个前缀和 (sum_{b,i}),表示 (b) 这个数,在前 (i) 位中出现的次数
假设在 vector 中记录的整数第 (x)(a) 的位置是 (pos1),倒数第 (x) 个位置是 (pos2),那么中间 (b) 的个数就是 (sum_{b,pos2}-sum_{b,pos1-1})
然后给所有枚举到的 (b) 取一个 (max) 就行

注意在 (pos1,pos2) 中,要分别先 push_back 一个 (0)(n+1),意思是正数倒数第 (0) 第出现的位置,同时方便后面的枚举

每枚举一个 (a),设它出现的次数为 (num_a),则它的复杂度为 (200 imes num_a)
那么总复杂度是 (sum_{i=1}^{200}num_a imes 200=200 imes n)

赛时没想到这点导致并没有交 E2 qaq

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<vector>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
	register int x=0;register int y=1;
	register char c=std::getchar();
	while(c<‘0‘||c>‘9‘){if(c==‘-‘) y=0;c=std::getchar();}
	while(c>=‘0‘&&c<=‘9‘){x=x*10+(c^48);c=std::getchar();}
	return y?x:-x;
}
int sum[206][200006];
std::vector<int>pos1[206],pos2[206];
int num[206];
int a[200006];
int main(){int T=read();while(T--){
//		std::printf("%lld",sizeof sum+sizeof pos1+sizeof pos2+sizeof a);
	int n=read();
	for(reg int i=1;i<=200;i++){
		pos1[i].clear();pos2[i].clear();
		pos1[i].push_back(0);pos2[i].push_back(n+1);
	}
	for(reg int x,i=1;i<=n;i++){
		for(x=1;x<=200;x++) sum[x][i]=sum[x][i-1];
		a[i]=read();sum[a[i]][i]++;
		num[a[i]]++;pos1[a[i]].push_back(i);
	}
	for(reg int i=n;i;i--) pos2[a[i]].push_back(i);
	reg int ans=0;
	for(reg int a=1;a<=200;a++){
		for(reg int x=0;x<=num[a]>>1;x++){
			for(reg int b=1;b<=200;b++)
				ans=std::max(ans,(x<<1)+sum[b][pos2[a][x]-1]-sum[b][pos1[a][x]]);
		}
	}
	std::printf("%d
",ans);
	std::memset(num,0,sizeof num);
	for(reg int x,i=1;i<=n;i++){
		for(x=1;x<=200;x++) sum[x][i]=0;
	}
}
	return 0;
}

以上是关于CF1335E Three Blocks Palindrome的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1335E2 - Three Blocks Palindrome (hard version)

Codeforces 1335E2 - Three Blocks Palindrome (贪心)

Codeforces 1335E1 - Three Blocks Palindrome (easy version)

CF-div3-635-E - Three Blocks Palindrome| 二分

python three_blocks.py

codeforces-1335-E Three Blocks Palindrome