题意:
解法:
对于字符x,
设串为. . . x. . . x. . . x. . . x. . .
显然第1 个x一定是和第4 个x匹配,
显然第2 个x一定是和第3 个x匹配.
每次我们选出移动代价最小的两个匹配字符, 移动到两边并删除即可.
每次删除, 由于数会移动, 所有数的下标会改变, 用线段树维护下标即可.
code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxm= 1e6 + 5 ;
const int mod= 1e9 + 7 ;
struct Tree{
int laz[ maxm<< 2 ] ;
int a[ maxm<< 2 ] ;
void pd ( int node) {
if ( laz[ node] ) {
a[ node* 2 ] + = laz[ node] ;
a[ node* 2 + 1 ] + = laz[ node] ;
laz[ node* 2 ] + = laz[ node] ;
laz[ node* 2 + 1 ] + = laz[ node] ;
laz[ node] = 0 ;
}
}
void add ( int st, int ed, int val, int l, int r, int node) {
if ( st<= l&& ed>= r) { a[ node] + = val, laz[ node] + = val; return ; }
pd ( node) ; int mid= ( l+ r) / 2 ;
if ( st<= mid) add ( st, ed, val, l, mid, node* 2 ) ;
if ( ed> mid) add ( st, ed, val, mid+ 1 , r, node* 2 + 1 ) ;
}
int ask ( int x, int l, int r, int node) {
if ( l== r) return a[ node] ;
pd ( node) ; int mid= ( l+ r) / 2 ;
if ( x<= mid) return ask ( x, l, mid, node* 2 ) ;
else return ask ( x, mid+ 1 , r, node* 2 + 1 ) ;
}
void build ( int l, int r, int node) {
if ( l== r) { a[ node] = l; return ; }
int mid= ( l+ r) / 2 ;
build ( l, mid, node* 2 ) ; build ( mid+ 1 , r, node* 2 + 1 ) ;
}
} T;
vector< int > g[ 26 ] ;
int cur[ maxm] ;
char s[ maxm] ;
int n;
void solve ( ) {
cin>> ( s+ 1 ) ;
n= strlen ( s+ 1 ) ;
T. build ( 1 , n, 1 ) ;
for ( int i= 1 ; i<= n; i++ ) {
g[ s[ i] - 'a' ] . push_back ( i) ;
}
int cnt= 0 ;
for ( int i= 0 ; i< 26 ; i++ ) {
if ( ( int ) g[ i] . size ( ) % 2 ) cnt++ ;
}
if ( cnt> 1 ) {
cout<< - 1 << endl; return ;
}
int len= n;
int ans= 0 ;
while ( 1 ) {
int mi= 1e9 , i1= - 1 ;
int lc= - 1 , rc= - 1 ;
for ( int i= 0 ; i< 26 ; i++ ) {
if ( ( int ) g[ i] . size ( ) - cur[ i] * 2 >= 2 ) {
int l= g[ i] [ cur[ i] ] ;
int r= g[ i] [ ( int ) g[ i] . size ( ) - 1 - cur[ i] ] ;
int pl= T. ask ( l, 1 , n, 1 ) , pr= T. ask ( r, 1 , n, 1 ) ;
int dif= ( pl- 1 ) + ( len- pr) ;
if ( dif< mi) mi= dif, lc= l, rc= r, i1= i;
}
}
if ( mi== 1e9 ) break ;
cur[ i1] ++ ;
ans+ = mi;
if ( lc+ 1 <= rc- 1 ) T. add ( lc+ 1 , rc- 1 , - 1 , 1 , n, 1 ) ;
if ( rc+ 1 <= n) T. add ( rc+ 1 , n, - 2 , 1 , n, 1 ) ;
len- = 2 ;
}
cout<< ans<< endl;
}
signed main ( ) {
ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ;
solve ( ) ;
return 0 ;
}