Submission #2206025
Source Code Expand
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0; i<(n); i++)
#define reps(i,x,n) for(int i=x; i<(n); i++)
#define rrep(i,n) for(int i=(n)-1; i>=0; i--)
#define all(X) (X).begin(),(X).end()
#define X first
#define Y second
#define pb push_back
#define eb emplace_back
using namespace std;
typedef long long int ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class A, size_t N, class T> void Fill(A (&a)[N], const T &v){ fill( (T*)a, (T*)(a+N), v ); }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {os<<"{"; rep(i,t.size()) {os<<t[i]<<",";} os<<"}"; return os;}
template<class T,size_t n> ostream& operator<<(ostream &os, const array<T,n> &t) {os<<"{"; rep(i,n) {os<<t[i]<<",";} os<<"}"; return os;}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}
const ll INF = 1e9+7;
class BIT {
int n;
vector<int> vs;
public:
BIT(int size) {
n = size;
vs = vector<int>(n);
}
//O(log n)
void add(int k, int a) {
for(int i = k; i < n; i |= i + 1) vs[i] += a;
}
//[s,t) O(log n)
int sum(int s, int t) {
if(s > 0) return sum(0, t) - sum(0, s);
int res = 0;
for(int i = t - 1; i >= 0; i = (i & (i + 1)) - 1) res += vs[i];
return res;
}
};
// 各ノードの情報
template <typename T>
struct node {
T v, lazy;
node(){
v = INF;
lazy = {};
}
// ノードの値の更新
void merge(T vl, T vr){
v = min(vl, vr);
}
// ノードの値の更新(lazy適用)
T add(int l, int r, T _v={}){
T sum = lazy + _v;
v += sum;
lazy = 0;
return sum;
}
// 遅延分の変更(加算)
void addLazy(T v){
lazy += v;
// lazy.X += v.X;
// lazy.Y += v.Y;
}
};
template <typename T, typename NODE=node<T> >
class SegTree{
// 遅延分の適応と伝播(現在のノードの値を確定させてLazyを伝搬させる)
void propLazy(int a, int b, int k, T v={}){
T lazy = data[k].add(a, b, v);
if( k < N ){
data[k*2+0].addLazy(lazy);
data[k*2+1].addLazy(lazy);
}
}
// セグメントツリーをたどる
inline T prop(int l, int r, T v, int a, int b, int k=1){
// 今いるノードの値を確定させる
propLazy(a, b, k);
// たどる
NODE nd; // 結果保存用(範囲外の場合は初期値が返る)
if( l <= a && b <= r ){
// 完全に範囲内の場合
propLazy(a, b, k, v);
return data[k].v;
}else if( l < b && a < r ){
// 中途半端に含まれる場合
int m = (a+b) / 2;
T vl = prop(l,r,v, a, m, k*2);
T vr = prop(l,r,v, m, b, k*2+1);
data[k].merge( data[k*2].v, data[k*2+1].v );
nd.merge( vl, vr );
}
return nd.v;
}
public:
vector<NODE> data;
int N;
SegTree(int _N){
// _N <= (N = 2^k) を満たすNを見つける
N = 1;
while( N < _N ) N<<=1;
data.resize(N*2);
}
// セグメントツリーの更新(指定した場所の値をvに変更)
void update(int l, T v){
// auto _v = v;
// _v.X -= get(l).X;
// _v.Y -= get(l).Y;
// prop(l, l+1, _v, 0, N);
prop(l, l+1, v - get(l), 0, N);
}
// セグメントツリーの更新(範囲に加算)
T add(int l, int r, T v){
return prop(l,r,v,0,N);
}
// 値を取得 [l,r)
T get(int l, int r){
return prop(l,r,{},0,N);
}
// 値を取得 [l,l+1)
T get(int l){
return prop(l,l+1,{},0,N);
}
};
typedef complex<ll> C;
int main(){
ios_base::sync_with_stdio(false);
string S;
cin >> S;
int N = S.length();
int cnt[30]={};
for(auto c: S) cnt[c-'a']++;
int odd = 0;
for(char c='a'; c<='z'; c++) if(cnt[c-'a']%2) odd++;
if( odd > 1 ){
cout << -1 << endl;
return 0;
}
vector<SegTree<int>> sg(30, N+1);
vector<SegTree<int>> Pos(30, N+1);
BIT btI(N+1);
BIT btD(N+1);
rep(i,N){
int k = S[i] - 'a';
sg[k].update(i, i);
Pos[k].update(i, i);
}
ll ans = 0;
string T;
rep(i,N/2){
vector<pii> v;
rep(k,26) if(cnt[k] > 1){
//ll idx = sg[k].get(i, N+1);
ll idx = Pos[k].get(0, N+1);
v.emplace_back(idx, k);
}
sort(all(v));
int k = v[0].Y;
int ad = btI.sum(0, v[0].X) - btD.sum(0, v[0].X+1);
ans += v[0].X + ad - i;
T += 'a' + k;
cnt[k] -= 2;
int pos = Pos[k].get(i, N+1);
sg[k].update(pos, INF);
Pos[k].update(pos, INF);
//rep(j,26) sg[j].add(0, pos, 1);
btI.add(0, 1);
btD.add(pos, 1);
}
if( odd ) rep(k,26) if(cnt[k] % 2){
T += 'a' + k;
cnt[k] -= 1;
//auto idx = sg[k].get(N/2, N+1);
auto pos = Pos[k].get(0, N+1);
int ad = btI.sum(0, pos) - btD.sum(0, pos+1);
//cout << btD.sum(pos, N+1) << endl;
ans += pos + ad - N/2;
sg[k].update(pos, INF);
Pos[k].update(pos, INF);
//rep(j,26) sg[j].add(0, pos, 1);
btI.add(0, 1);
btD.add(pos, 1);
break;
}
rep(i,N/2){
int k = T[N/2-i-1] - 'a';
//auto idx = sg[k].get(i+N/2, N+1);
auto pos = Pos[k].get(0, N+1);
int ad = btI.sum(0, pos) - btD.sum(0, pos+1);
ans += pos + ad - (i + N/2 + odd);
T += 'a' + k;
sg[k].update(pos, INF);
Pos[k].update(pos, INF);
//rep(j,26) sg[j].add(0, pos, 1);
btI.add(0, 1);
btD.add(pos, 1);
}
//cout << T << endl;
cout << ans << endl;
return 0;
}
Submission Info
Submission Time |
|
Task |
E - Papple Sort |
User |
oyas |
Language |
C++14 (GCC 5.4.1) |
Score |
800 |
Code Size |
5438 Byte |
Status |
AC |
Exec Time |
1779 ms |
Memory |
252432 KB |
Judge Result
Set Name |
Sample |
All |
Score / Max Score |
0 / 0 |
800 / 800 |
Status |
|
|
Set Name |
Test Cases |
Sample |
s1.txt, s2.txt, s3.txt |
All |
01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, 31.txt, 32.txt, 33.txt, 34.txt, 35.txt, 36.txt, 37.txt, 38.txt, 39.txt, 40.txt, 41.txt, 42.txt, 43.txt, 44.txt, 45.txt, 46.txt, 47.txt, s1.txt, s2.txt, s3.txt |
Case Name |
Status |
Exec Time |
Memory |
01.txt |
AC |
1393 ms |
250384 KB |
02.txt |
AC |
1766 ms |
250384 KB |
03.txt |
AC |
1749 ms |
250384 KB |
04.txt |
AC |
1779 ms |
250384 KB |
05.txt |
AC |
1611 ms |
250384 KB |
06.txt |
AC |
1755 ms |
250384 KB |
07.txt |
AC |
1511 ms |
250384 KB |
08.txt |
AC |
1721 ms |
250384 KB |
09.txt |
AC |
1728 ms |
250512 KB |
10.txt |
AC |
1709 ms |
250384 KB |
11.txt |
AC |
2 ms |
720 KB |
12.txt |
AC |
2 ms |
720 KB |
13.txt |
AC |
2 ms |
720 KB |
14.txt |
AC |
2 ms |
720 KB |
15.txt |
AC |
590 ms |
250384 KB |
16.txt |
AC |
589 ms |
250384 KB |
17.txt |
AC |
597 ms |
250512 KB |
18.txt |
AC |
606 ms |
250512 KB |
19.txt |
AC |
590 ms |
250384 KB |
20.txt |
AC |
2 ms |
720 KB |
21.txt |
AC |
619 ms |
250384 KB |
22.txt |
AC |
626 ms |
250384 KB |
23.txt |
AC |
596 ms |
250384 KB |
24.txt |
AC |
2 ms |
720 KB |
25.txt |
AC |
570 ms |
252432 KB |
26.txt |
AC |
599 ms |
250384 KB |
27.txt |
AC |
613 ms |
250384 KB |
28.txt |
AC |
603 ms |
250384 KB |
29.txt |
AC |
607 ms |
250384 KB |
30.txt |
AC |
2 ms |
720 KB |
31.txt |
AC |
587 ms |
250384 KB |
32.txt |
AC |
2 ms |
720 KB |
33.txt |
AC |
612 ms |
250384 KB |
34.txt |
AC |
2 ms |
720 KB |
35.txt |
AC |
621 ms |
250384 KB |
36.txt |
AC |
2 ms |
720 KB |
37.txt |
AC |
2 ms |
720 KB |
38.txt |
AC |
2 ms |
720 KB |
39.txt |
AC |
653 ms |
250384 KB |
40.txt |
AC |
2 ms |
720 KB |
41.txt |
AC |
1 ms |
256 KB |
42.txt |
AC |
1 ms |
256 KB |
43.txt |
AC |
1 ms |
256 KB |
44.txt |
AC |
1 ms |
256 KB |
45.txt |
AC |
1 ms |
256 KB |
46.txt |
AC |
1 ms |
256 KB |
47.txt |
AC |
1 ms |
256 KB |
s1.txt |
AC |
1 ms |
256 KB |
s2.txt |
AC |
1 ms |
256 KB |
s3.txt |
AC |
1 ms |
256 KB |