前言
我的证明:这似乎非常对啊。
。。。
解析
直观感受:字母交错出现非常愚蠢。
然后就猜对了
为什么?
考虑两个相同但不相邻的字符
T
i
,
T
j
T_i,T_j
Ti,Tj,对应位置为
p
i
,
p
j
p_i,p_j
pi,pj。
夹在中间的字符
k
k
k 无非三种可能。
- p i < p k < p j p_i<p_k<p_j pi<pk<pj,此时无论是把i移到后面还是把j移到前面都会增加一个逆序对。
- p k < p i < p j p_k<p_i<p_j pk<pi<pj,此时把j移到前面会增加一个逆序对,把i移到后面会减少一个逆序对。
- p i < p j < p k p_i<p_j<p_k pi<pj<pk,此时把i移到后面会增加一个逆序对,把j移到前面会减少一个逆序对。
那么我们只需要讨论一下2、3两种情况那种更多,按照对应策略操作,就可以把
T
i
,
T
j
T_i,T_j
Ti,Tj 挪到一起,且逆序对不减少。
证毕。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned ll
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("ok\n")
const int N=1e5+100;
const bool Flag=1;
inline ll read() {
ll x(0),f(1);char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
bool mem1;
int n;
char s[N],ch[5],ans[N],tmp[N];
int cnt[5],sum[N][5];
int q[5],vis[5];
ll mx;
map<char,int>mp;
queue<int>qq[5];
int f[N];
inline void add(int p,int w){
for(;p<=n;p+=p&-p) f[p]+=w;
return;
}
inline int ask(int p){
int res(0);
for(;p;p-=p&-p) res+=f[p];
return res;
}
ll calc(){
ll res(0);
for(int i=1;i<=n;i++){
qq[mp[tmp[i]]].push(i);
f[i]=i&-i;
}
for(int i=1;i<=n;i++){
int p=qq[mp[s[i]]].front();
qq[mp[s[i]]].pop();
int pos=i-1+ask(p);
add(p,-1);
res+=pos-i;
}
return res;
}
void dfs(int k){
if(k>4){
int num(0);
for(int i=1;i<=4;i++){
for(int j=1;j<=cnt[q[i]];j++) tmp[++num]=ch[q[i]];
}
//printf("%s\n",tmp+1);
ll o=calc();
if(o>mx){
mx=o;
memcpy(ans,tmp,sizeof(char)*(n+1));
}
return;
}
for(int i=1;i<=4;i++){
if(vis[i]) continue;
vis[i]=1;
q[k]=i;
dfs(k+1);
vis[i]=0;
}
return;
}
void work(){
scanf(" %s",s+1);
n=strlen(s+1);
mx=-1;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++){
cnt[mp[s[i]]]++;
for(int j=1;j<=4;j++) sum[i][j]=sum[i-1][j];
sum[i][mp[s[i]]]++;
}
//scanf(" %s",tmp+1);
//printf("tmp=%lld\n",calc());
dfs(1);
for(int i=1;i<=n;i++) putchar(ans[i]);
puts("");
//printf("mx=%lld\n",mx);
}
bool mem2;
signed main() {
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
ch[1]='A';ch[2]='N';
ch[3]='O';ch[4]='T';
mp['A']=1;
mp['N']=2;
mp['O']=3;
mp['T']=4;
int T=read();
while(T--) work();
return 0;
}