标签:read 位置 lang pre rac include printf 表示 code
就是我这个菜鸡,赛时写出了 E2 的做法,但是算错复杂度,导致以为自己的做法只能AC E1,就没交到 E2 上,然后赛后秒A.....
定义一种字串为形如:\([\underbrace{a, a, \dots, a}_{x}, \underbrace{b, b, \dots, b}_{y}, \underbrace{a, a, \dots, a}_{x}]\)
问你在给定的字串中,符合这种要求的最大子序列(可以不连续)的长度
给出数列长度 \(n\le 2\cdot 10^5\),数列中每个数 \(a_i\le 200\)
考虑暴力枚举 \(a\),然后对于每一个 \(a\),枚举 \(x\),也就是两边的 \(a\) 的 个数
用两个 vector
,分别记录从前和从后数,第 \(x\) 个 \(a\) 的位置
然后一直枚举到第 \(\lfloor\dfrac{\text{a出现的次数}}{2}\rfloor\) 个
此时,再暴力枚举 \(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\times num_a\)
那么总复杂度是 \(\sum_{i=1}^{200}num_a\times 200=200\times 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\n",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
标签:read 位置 lang pre rac include printf 表示 code
原文地址:https://www.cnblogs.com/suxxsfe/p/12696998.html