题解/算法 {G - Bracelet}
@LINK: https://codeforces.com/gym/105184
;
对于环形数组 比如A: [a,b,c,d,e]
长度为N
(a,e
首尾连接), 把他复制拼接 形成新数组B: [a,b,c,d,e, a,b,c,d,e]
, 此时 原环形数组A的任意一段 和 B的任意长度<=N
的子数组 两者是双射关系 (比如A的[d,e,a,b]
段 对应 B的[3-6]子数组
);
我们能拼接出来的子数组 其长度一定是偶数; 因此 枚举B的子数组[l, r]
满足r-l+1 为偶数
, 通过双指针 判断当前[l-r]
区间里 00,11, 01/10
的个数;
此时分为两种情况: l: {偶数/ 奇数}
, 要单独处理;
int A, B, C; cin>> A>> B>> C;
string S; cin>> S;
S += S;
int ANS = 0;
int N = S.size();
for( int a=0,b=0,c=0, l=0, r=1; r < N; r += 2){
auto Modify = [&]( int _l, int _f){
if( S[_l] == S[_l+1]){
if( S[_l] == '0'){
a += _f;
}
else{ c += _f;}
} else{ b += _f;}
};
Modify( r-1, 1);
while( a>A || b>B || c>C || (r-l+1 > N/2)){
Modify( l, -1);
l += 2;
}
ASSERT_( l <= r+1, l, r);
ANS = std::max( ANS, r-l+1);
}
for( int a=0,b=0,c=0, l=1, r=2; r < N; r += 2){
auto Modify = [&]( int _l, int _f){
if( S[_l] == S[_l+1]){
if( S[_l] == '0'){
a += _f;
}
else{ c += _f;}
} else{ b += _f;}
};
Modify( r-1, 1);
while( a>A || b>B || c>C || (r-l+1 > N/2)){
Modify( l, -1);
l += 2;
}
ASSERT_( l <= r+1, l, r);
ANS = std::max( ANS, r-l+1);
}
ANS = std::min( ANS, N/2);
cout<< ANS;