又是一个逐步简化的模型,好烦了又不会做这种题了呜啊呜啊。


首先相邻且相同的字符,我们可以缩在一起。

不妨假设 \(c_a\leq c_b\leq c_c\),我们考虑逐步删除来达到三个字符相同的情况。

按照 \(A\) 将整个字符串划分成若干段,每一段一定形如 \(BC\) 交错的情形。

注意到中间字符串长度大于等于 \(3\) 时删除 \(BC\) 原串仍然满足相邻字符不相同这个性质,猜测 \(c_b=c_c\) 时可以取到上界。

证明:若一直删除 \(BC\),最后两个 \(A\) 之间至多两个字符,两边至多一个字符,那么 \(c_b+c_c\leq 2(c_a-1)+2=2c_a\),而一开始 \(c_b+c_c\geq 2c_a\),那么删除过程中一定会满足 \(c_b+c_c=2c_a\)


那么我们现在的目标就是保证 \(c_a\) 尽量大的情况下使得 \(c_b=c_c\),首先如果说可以单独删除一个 \(C\) 一定会删除的,当两个 \(A\) 之间的字符串长度大于等于 \(2\) 的时候就可以将两边的 \(C\) 字符删掉。

如果还是不行的话,那么单个 \(C\) 的段一定比 \(B\) 的段多,我们一直删除 \(AC/CA\) 即可。

#include<bits/stdc++.h>
using namespace std;
#define N 1000005
char s[N];
int n,m,pos[3];
pair<int,int> mp[3];
int a[N],b[N];
void copy(){for(int i=1;i<=n;i++)b[i]=a[i];m=0;}
void output(){for(int i=1;i<=n;i++)printf("%d",a[i]);puts("");}
void makeeq(){
	int x=0,y=0,z=0;
	for(int i=1;i<=n;i++)
		if(a[i]==0)++x;
		else if(a[i]==1)++y;
		else ++z;
	copy();
	for(int l=1,r=1;l<=n;l=++r)
		if(b[l]!=0){
			while(r<n&&b[r+1]!=0)++r;
			if(r-l+1>=2){
				if(b[l]==2){
					if(z>y)--z;
					else a[++m]=b[l];
				}else a[++m]=b[l];
				for(int i=l+1;i<r;i++)a[++m]=b[i];
				if(b[r]==2){
					if(z>y)--z;
					else a[++m]=b[r];
				}else a[++m]=b[r];
			} 
			else if(z>y&&b[l]==2&&(l==1||r==n))--z;
			else a[++m]=b[l];
		}else a[++m]=b[l];
	n=m;
	if(z==y)return;
	copy();
	for(int i=1;i<=n;i++){
		if(z>y&&i<=n-1&&(b[i]==0&&b[i+1]==2||b[i]==2&&b[i+1]==0))++i,--z;
		else a[++m]=b[i];
	}
	n=m;
}
void getup(){
	int x=0,y=0,z=0;
	for(int i=1;i<=n;i++)
		if(a[i]==0)++x;
		else if(a[i]==1)++y;
		else ++z;
	copy();
	for(int l=1,r=1;l<=n;l=++r)
		if(b[l]!=0){
			while(r<n&&b[r+1]!=0)++r;
			while(r-l+1>2&&y>x)l+=2,--y;
			if(y>x&&r-l+1==2&&(l==1||r==n))l+=2,--y;
			for(int i=l;i<=r;i++)a[++m]=b[i];
		}
		else a[++m]=b[l];
	n=m;
}
int main(){
	for(int i=0;i<3;i++)mp[i].second=i;
	scanf("%s",s+1);n=strlen(s+1);
	for(int i=1;i<=n;i++)a[i]=s[i]-'A';
	copy();
	for(int i=1;i<=n;i++)if(i==1||b[i]!=b[i-1])a[++m]=b[i],++mp[b[i]].first;n=m;
	sort(mp,mp+3);
	for(int i=0;i<3;i++)pos[mp[i].second]=i;
	for(int i=1;i<=n;i++)a[i]=pos[a[i]];
	makeeq();
	getup();
	assert(n%3==0);
	for(int i=1;i<=n;i++)printf("%c",mp[a[i]].second+'A');
}