相邻的相等串直接当成一个串。
不妨设\(A\le B,A\le C\)
考虑\(A\)选哪些已经确定的时候,如何调整\(B\)和\(C\)。
把不用的\(A\)提出去之后再合并一下形成串\(T\)。不难发现\(A\le B, A\le C\)仍然成立。
- \(B=C\)的情况
我们直接删除连续的\(BC\)串即可。
容易证明一定能够做到。
- \(B\ne C\)的情况,不妨设\(B
现在有\(A+1\)个子串。定义\(\text{unit string}\)为长度为\(1\)并且左右都会\(>1\)的子串。设\(x,y\)分别为包含\(B\)的串数量和\(C\)的\(\text{unit string}\)数量。
如果\(x
如果\(x\ge y\),那么是一定可以只删除\(C\)就直接做到\(B= C\)的。
\(b_1,b_2,c_1,c_2\)分别表示\(B/C\text{的string/unit string}\)个数。
现在相当于要求\(b_2\le c_1\)并且\(c_2\le b_1\)
首先两个条件只会不满足一个。
- 删掉一个\(A\),四个值最多\(-1\)
- 如果删掉的\(A\)左边是一个\(b_2\)类型的串,\(b_2\)会\(-1\)而\(c_1\)不会变。那直接依次删掉即可。根据\((1)\),这样显然达到最优秀了
代码
#include
using namespace std;
const int N = 4e6+5;
int s[N],n;char tmple[N];
int cnt[3];
int p[3]={0,1,2};
inline void _swap(int x,int y){
swap(p[x],p[y]);
for(int i=1;i<=n;i++){
if(s[i]==x)s[i]=y;
else if(s[i]==y)s[i]=x;
}
}
int b1,b2,c1,c2;
vector pc2;bool ban[N];
void get(int l,int r){
if(l>r)return ;
int cntt[3]={0,0,0};
for(int i=l;i<=r;i++){
cntt[s[i]]++;
}
if(cntt[2]==0||cntt[1]==0){
if(cntt[2]&&l>1&&r1&&rr)return ;
if(l==r){
if(l==1||l==n){
if(s[l]==2&&cnt[2]>cnt[1])cnt[2]--,ban[l]=1;
}
}
if(l==r)return ;
if(s[l]==2&&cnt[2]>cnt[1])cnt[2]--,ban[l]=1;
if(s[r]==2&&cnt[2]>cnt[1])cnt[2]--,ban[r]=1;
}
int now,tar;
void Sol2(int l,int r){
if(l>r)return ;
while(ltar){
if(l+1>=r && l!=1 && r!=n)break;
now--;ban[l]=ban[l+1]=1;l+=2;
}
}
int main()
{
scanf("%s",tmple+1);int lll=strlen(tmple+1);
for(int i=1;i<=lll;i++)if(i==1||tmple[i]!=tmple[i-1])s[++n]=tmple[i]-'A';
for(int i=1;i<=n;i++)cnt[s[i]]++;
for(int i=0;i<3;i++)for(int j=i+1;j<3;j++)if(i!=j){
if(cnt[i]>cnt[j]){
_swap(i,j);
swap(cnt[i],cnt[j]);
}
}
int lst=0;
for(int i=1;i<=n;i++)
if(s[i]==0){get(lst+1,i-1);lst=i;}
get(lst+1,n);
if(b1