题解:P3590 [POI 2015] TRZ
P3590 题解
题面
思路
由于这个帖子没有人给出 hack,所以我就照着这个思路开始证明。
结论:最终答案的左端点在 \(1\sim3\) 的位置之一或者右端点在 \(n-2\sim n\) 的位置之一。
假设目前的字符串 a1 a2 a3 res a4 a5 a6,其中 \(res\) 为当前的最优解。
- \(res\) 中只有一个字符 \(ch\),则有两种情况。
- \(|ch|=1\),则 \(res\) 可以在 \(a_{1\sim6}\) 里任意一个,所以满足结论。
- \(|ch|>1\),则单独考虑
res a4,若 \(a_4=ch\),则 \(res\) 可以扩展;若 \(a_4\neq ch\),则 \(|a_4|=1\),此时 \(|a_4|\neq|ch|\),所以在这种情况下,结论成立。
- \(res\) 中有多个字符,那么这三个字符的出现次数不一样,不妨设 \(|B|>|C|>|S|\),则又有三种情况。
- \(a_3=\)
B或 \(a_4=\)B,则 \(res\) 可以继续往外扩展。 - \(a_3=\)
C或 \(a_4=\)C,设 \(a_4=\)C,若 \(res\) 可以扩展到 \(a_4\),则满足结论;若不能扩展到 \(a_4\),则有 \(|B|=|C|+1\),接下来考虑扩展 \(a_3,a_5\),若 \(a_3,a_5\) 中有一个为B或C,则可以扩展;若 \(a_3,a_5=\)S,于是考虑a3 res即S res,若 \(res\) 可以扩展到 \(a_3\),则满足结论;若不能扩展,则有 \(|C|=|S|+1\),于是联立下前面的式子,\(res\) 里字母数量满足 \(|B|=|C|+1=|S|+2\)。继续讨论,若 \(a_2=\)B,则a2 a3 res a4即B S res C满足题意;若 \(a_2=\)C,则a2 a3 res a4即C S res C满足题意;若 \(a_2=\)S,继续讨论 \(a_1\),若 \(a_1=\)B,则a1 a2 a3 res即B S S res满足题意;若 \(a_1=\)S,则a1 a2 a3 res即S S S res满足题意;若 \(a_1=\)C,继续讨论 \(a_6\),若 \(a_6=\)B,则res a4 a5 a6即res C S B满足题意;若 \(a_6=\)C,则res a4 a5 a6即res C S C满足题意;若 \(a_6=\)S,则a1 a2 a3 res a4 a5 a6即C S S res C S S满足题意。综上所述,当 \(a_4=\)C时,\(res\) 可以扩展。 - \(a_3,a_4=\)
S(一个为S的情况上面已经讨论),若a3 res和a3 res a4都不能扩展,则有 \(|B|=|C|+1=|S|+2\),接下来考虑 \(a_2,a_5\),若 \(a_2,a_5=\)B,则a2 a3 res a4即C S res S满足题意,\(a_5\) 同理也满足题意;若 \(a_2,a_5=\)S,则a2 a3 res a4即S S res S满足题意,\(a_5\) 同理也满足题意;若 \(a_2,a_5=\)C,继续考虑 \(a_1,a_6\),若 \(a_1,a_6=\)B,则a1 a2 a3 res即B C S res满足题意,\(a_6\) 同理也满足题意;若 \(a_1,a_6=\)C,则a1 a2 a3 res即C C S res满足题意,\(a_6\) 同理也满足题意;若 \(a_1,a_6=\)S,则a1 a2 a3 res a4 a5 a6即S C S res S C满足题意,\(a_6\) 同理也满足题意。综上所述,\(a_3,a_4=\)S时,\(res\) 可以扩展。
- \(a_3=\)
证毕,所以只要用前缀和记录下字符串字母出现的次数,一个个判断过去即可,时间复杂度为 \(O(n)\)。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int MN=1e6+5;
ll n,s[MN][3],ans=1;
char c[MN];
void write(ll n){if(n<0){putchar('-');write(-n);return;}if(n>9)write(n/10);putchar(n%10+'0');}
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
char gc(){char ch=getchar();while(ch!='B'&&ch!='C'&&ch!='S')ch=getchar();return ch;}
ll gs(char ch){if(ch=='C') return 0;if(ch=='B') return 1;return 2;}
int main(){
n=read();
for(int i=1; i<=n; i++){
c[i]=gc();
s[i][gs(c[i])]++;
}
for(int i=1; i<=n; i++) for(int j=0; j<3; j++) s[i][j]+=s[i-1][j];
for(int i=1; i<=3; i++) for(int j=n; j>i; j--) if((s[j][0]-s[i-1][0]!=s[j][1]-s[i-1][1]&&s[j][1]-s[i-1][1]!=s[j][2]-s[i-1][2]&&s[j][0]-s[i-1][0]!=s[j][2]-s[i-1][2])||(s[j][0]-s[i-1][0]+s[j][1]-s[i-1][1]+s[j][2]-s[i-1][2]==s[j][0]-s[i-1][0])||(s[j][0]-s[i-1][0]+s[j][1]-s[i-1][1]+s[j][2]-s[i-1][2]==s[j][1]-s[i-1][1])||(s[j][0]-s[i-1][0]+s[j][1]-s[i-1][1]+s[j][2]-s[i-1][2]==s[j][2]-s[i-1][2])) ans=max(ans,(ll)j-i+1);
for(int j=n; j>n-3; j--) for(int i=1; i<j; i++) if((s[j][0]-s[i-1][0]!=s[j][1]-s[i-1][1]&&s[j][1]-s[i-1][1]!=s[j][2]-s[i-1][2]&&s[j][0]-s[i-1][0]!=s[j][2]-s[i-1][2])||(s[j][0]-s[i-1][0]+s[j][1]-s[i-1][1]+s[j][2]-s[i-1][2]==s[j][0]-s[i-1][0])||(s[j][0]-s[i-1][0]+s[j][1]-s[i-1][1]+s[j][2]-s[i-1][2]==s[j][1]-s[i-1][1])||(s[j][0]-s[i-1][0]+s[j][1]-s[i-1][1]+s[j][2]-s[i-1][2]==s[j][2]-s[i-1][2])) ans=max(ans,(ll)j-i+1);
write(ans);putchar('\n');
return 0;
}

浙公网安备 33010602011771号