Problem p03483 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define REP(i, n) for (long long i = 0; i < (n); i++)
#define FOR(i, m, n) for (long long i = (m); i < (n); ++i)
#define ALL(obj) (obj).begin(), (obj).end()
#define SPEED                                                                  \
  cin.tie(0);                                                                  \
  ios::sync_with_stdio(false);

template <class T> using V = vector<T>;
template <class T, class U> using P = pair<T, U>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQR = priority_queue<T, vector<T>, greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433;

template <class T> vector<T> multivector(size_t N, T init) {
  return vector<T>(N, init);
}
template <class... T> auto multivector(size_t N, T... t) {
  return vector<decltype(multivector(t...))>(N, multivector(t...));
}
template <class T> void corner(bool flg, T hoge) {
  if (flg) {
    cout << hoge << endl;
    exit(0);
  }
}
template <class T, class U>
ostream &operator<<(ostream &o, const map<T, U> &obj) {
  o << "{";
  for (auto &x : obj)
    o << " {" << x.first << " : " << x.second << "}"
      << ",";
  o << " }";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const set<T> &obj) {
  o << "{";
  for (auto itr = obj.begin(); itr != obj.end(); ++itr)
    o << (itr != obj.begin() ? ", " : "") << *itr;
  o << "}";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const multiset<T> &obj) {
  o << "{";
  for (auto itr = obj.begin(); itr != obj.end(); ++itr)
    o << (itr != obj.begin() ? ", " : "") << *itr;
  o << "}";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &obj) {
  o << "{";
  for (int i = 0; i < (int)obj.size(); ++i)
    o << (i > 0 ? ", " : "") << obj[i];
  o << "}";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const deque<T> &obj) {
  o << "{";
  for (int i = 0; i < (int)obj.size(); ++i)
    o << (i > 0 ? ", " : "") << obj[i];
  o << "}";
  return o;
}
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &obj) {
  o << "{" << obj.first << ", " << obj.second << "}";
  return o;
}
template <template <class tmp> class T, class U>
ostream &operator<<(ostream &o, const T<U> &obj) {
  o << "{";
  for (auto itr = obj.begin(); itr != obj.end(); ++itr)
    o << (itr != obj.begin() ? ", " : "") << *itr;
  o << "}";
  return o;
}
void print(void) { cout << endl; }
template <class Head> void print(Head &&head) {
  cout << head;
  print();
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
  cout << head << " ";
  print(forward<Tail>(tail)...);
}
template <class T> inline void chmax(T &a, const T b) { a = max(a, b); }
template <class T> inline void chmin(T &a, const T b) { a = min(a, b); }
void YN(bool flg) { cout << (flg ? "YES" : "NO") << endl; }
void Yn(bool flg) { cout << (flg ? "Yes" : "No") << endl; }
void yn(bool flg) { cout << (flg ? "yes" : "no") << endl; }

template <class Operator> class LazySegmentTree {
  Operator Op; // Operator 演算子、型、単位元を持つ
  using typeNode = decltype(Op.unitNode); // nodeの型
  using typeLazy = decltype(Op.unitLazy); // lazyの型
  size_t
      length; // セグメント木の最下段の要素の数(vectorの要素の数を超える2べきの数)
  size_t height;         // セグメント木の高さ
  vector<typeNode> node; // node
  vector<typeLazy> lazy; // lazy
  vector<int> width;     // width
public:
  // unitで初期化
  LazySegmentTree(const size_t num) {
    for (length = 1, height = 0; length < num; length *= 2, height++)
      ;
    node.resize(2 * length, Op.unitNode);
    lazy.resize(2 * length, Op.unitLazy);
    width.resize(2 * length, 0);
    for (int i = 0; i < num; ++i)
      node[i + length] = Op.unitNode;
    for (int i = length - 1; i >= 0; --i)
      node[i] = Op.funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
    for (int i = length; i < 2 * length; ++i)
      for (int j = i, k = 1; j && !width[j]; j >>= 1, k <<= 1)
        width[j] = k;
  }

  // //同じinitで初期化
  LazySegmentTree(const size_t num, const typeNode init) {
    for (length = 1, height = 0; length < num; length *= 2, height++)
      ;
    node.resize(2 * length, Op.unitNode);
    lazy.resize(2 * length, Op.unitLazy);
    for (int i = 0; i < num; ++i)
      node[i + length] = init;
    for (int i = length - 1; i >= 0; --i)
      node[i] = Op.funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
    width.resize(2 * length, 0);
    for (int i = length; i < 2 * length; ++i)
      for (int j = i, k = 1; j && !width[j]; j >>= 1, k <<= 1)
        width[j] = k;
  }

  // vectorで初期化
  LazySegmentTree(const vector<typeNode> &vec) {
    for (length = 1, height = 0; length < vec.size(); length *= 2, height++)
      ;
    node.resize(2 * length, Op.unitNode);
    lazy.resize(2 * length, Op.unitLazy);
    for (int i = 0; i < vec.size(); ++i)
      node[i + length] = vec[i];
    for (int i = length - 1; i >= 0; --i)
      node[i] = Op.funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
    width.resize(2 * length, 0);
    for (int i = length; i < 2 * length; ++i)
      for (int j = i, k = 1; j && !width[j]; j >>= 1, k <<= 1)
        width[j] = k;
  }

  void propagate(int k) {
    if (lazy[k] == Op.unitLazy)
      return;
    node[k] = Op.funcMerge(node[k], lazy[k], width[k]);
    if (k < length)
      lazy[2 * k + 0] = Op.funcLazy(lazy[2 * k + 0], lazy[k]);
    if (k < length)
      lazy[2 * k + 1] = Op.funcLazy(lazy[2 * k + 1], lazy[k]);
    lazy[k] = Op.unitLazy;
  }

  // idx : 0-indexed
  void update(int a, int b, typeLazy x) {
    int l = a + length, r = b + length - 1;
    for (int i = height; 0 < i; --i)
      propagate(l >> i), propagate(r >> i);
    for (r++; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = Op.funcLazy(lazy[l], x), propagate(l), l++;
      if (r & 1)
        --r, lazy[r] = Op.funcLazy(lazy[r], x), propagate(r);
    }
    l = a + length, r = b + length - 1;
    while ((l >>= 1), (r >>= 1), l) {
      if (lazy[l] == Op.unitLazy)
        node[l] =
            Op.funcNode(Op.funcMerge(node[(l << 1) + 0], lazy[(l << 1) + 0],
                                     width[(l << 1) + 0]),
                        Op.funcMerge(node[(l << 1) + 1], lazy[(l << 1) + 1],
                                     width[(l << 1) + 1]));
      if (lazy[r] == Op.unitLazy)
        node[r] =
            Op.funcNode(Op.funcMerge(node[(r << 1) + 0], lazy[(r << 1) + 0],
                                     width[(r << 1) + 0]),
                        Op.funcMerge(node[(r << 1) + 1], lazy[(r << 1) + 1],
                                     width[(r << 1) + 1]));
    }
  }

  //[l,r)
  typeNode get(int a, int b) {
    int l = a + length, r = b + length - 1;
    for (int i = height; 0 < i; --i)
      propagate(l >> i), propagate(r >> i);
    typeNode vl = Op.unitNode, vr = Op.unitNode;
    for (r++; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = Op.funcNode(vl, Op.funcMerge(node[l], lazy[l], width[l])), l++;
      if (r & 1)
        r--, vr = Op.funcNode(Op.funcMerge(node[r], lazy[r], width[r]), vr);
    }
    return Op.funcNode(vl, vr);
  }

  void print() {
    // cout << "node" << endl;
    // for(int i = 1,j = 1; i < 2*length; ++i) {
    // 	cout << node[i] << " ";
    // 	if(i==((1<<j)-1) && ++j) cout << endl;
    // }
    // cout << "lazy" << endl;
    // for(int i = 1,j = 1; i < 2*length; ++i) {
    // 	cout << lazy[i] << " ";
    // 	if(i==((1<<j)-1) && ++j) cout << endl;
    // }
    // cout << "width" << endl;
    // for(int i = 1,j = 1; i < 2*length; ++i) {
    // 	cout << width[i] << " ";
    // 	if(i==((1<<j)-1) && ++j) cout << endl;
    // }
    cout << "vector" << endl;
    cout << "{ " << get(0, 1);
    for (int i = 1; i < length; ++i)
      cout << ", " << get(i, i + 1);
    cout << " }" << endl;
  }
};

// node:総和　lazy:加算
template <class typeNode, class typeLazy> struct nodeSumLazyAdd {
  typeNode unitNode = 0;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return l + r; }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return l + r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) { return l + r * len; }
  // LazySegmentTree<nodeSumLazyPlus<ll,ll>> Seg(N,0);
};

// node:最小　lazy:加算
template <class typeNode, class typeLazy> struct nodeMinLazyAdd {
  typeNode unitNode = 1234567890;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return min(l, r); }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return l + r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) { return l + r; }
  // LazySegmentTree<nodeMinLazyAdd<ll,ll>> Seg(N,0);
  // verify https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_H
};

// node:mod和　lazy:mod加算
template <class typeNode, class typeLazy> struct nodeModSumLazyModAdd {
  typeNode unitNode = 0;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return (l + r) % MOD; }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return (l + r) % MOD; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) {
    return (l + (r * len) % MOD) % MOD;
  }
  // LazySegmentTree<nodeModSumLazyModAdd<ll,ll>> dp(N+3,0);
  // verify
  // https://atcoder.jp/contests/code-festival-2018-quala/tasks/code_festival_2018_quala_d
};

// node:最大　lazy:更新
template <class typeNode, class typeLazy> struct nodeMaxLazyUpdate {
  typeNode unitNode = 0;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return max(l, r); }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) {
    return r != 0 ? r * len : l;
  }
  // LazySegmentTree<nodeMaxLazyUpdate<ll,ll>> Seg(N+2,0);
  // verify
  // https://atcoder.jp/contests/nikkei2019-final/tasks/nikkei2019_final_d
};

// node:最小　lazy:更新
template <class typeNode, class typeLazy> struct nodeMinLazyUpdate {
  typeNode unitNode = 12345678910;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return min(l, r); }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) {
    return r != 0 ? r * len : l;
  }
  // LazySegmentTree<ll,ll,nodeMinLazyUpdate<ll,ll>> Seg(N,HIGHINF,0);
  // verify
  // https://atcoder.jp/contests/code-festival-2018-final/tasks/code_festival_2018_final_e
};

// node:GCD　lazy:更新
template <class typeNode, class typeLazy> struct nodeGCDLazyUpdate {
  typeNode unitNode = 0;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) {
    return ((r == 0) ? l : funcNode(r, l % r));
  }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) { return r != 0 ? r : l; }
  // LazySegmentTree<nodeGCDLazyUpdate<ll,ll>> Seg(A);
  // verify https://atcoder.jp/contests/abc125/tasks/abc125_c
};

// node:総和　lazy:更新
template <class typeNode, class typeLazy> struct nodeSumLazyUpdate {
  typeNode unitNode = 0;
  typeLazy unitLazy = -2000;
  typeNode funcNode(typeNode l, typeNode r) { return l + r; }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) {
    return r != -2000 ? r * len : l;
  }
  // LazySegmentTree<nodeSumLazyUpdate<ll,ll>> Seg(N,0,-2000,0);
  // verify https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_I
};

int main() {
  string S;
  cin >> S;
  vector<int> cnt(26, 0);
  ll N = S.size();
  for (int i = 0; i < N; ++i)
    cnt[S[i] - 'a']++;
  int s = 0;
  for (int i = 0; i < 26; ++i)
    s += cnt[i] % 2;
  corner(s > 2, -1);
  vector<multiset<ll>> vst(26);
  for (int i = 0; i < N; ++i)
    vst[S[i] - 'a'].insert(i);
  vector<ll> idx(N);
  iota(ALL(idx), 0);
  LazySegmentTree<nodeSumLazyAdd<ll, ll>> seg(N, 0);
  ll ans = 0;
  for (int i = 0; i < N; ++i) {
    ll d = seg.get(i, i + 1);
    ll x = idx[i];
    ll l = x - d;
    if (l < 0)
      continue;
    ll c = S[i] - 'a';
    if (vst[c].size() == 1) {
      for (int k = i + 1; k < N; ++k) {
        ll e = seg.get(k, k + 1);
        ll y = idx[k];
        if (y - e < 0)
          continue;
        swap(x, y);
        seg.update(i, i + 1, -d);
        seg.update(i, i + 1, e + 1);
        seg.update(k, k + 1, -e);
        seg.update(k, k + 1, d - 1);
        swap(idx[i], idx[k]);
        ll g = S[k] - 'a';
        vst[c].erase(vst[c].begin());
        vst[g].erase(vst[g].begin());
        vst[c].insert(k);
        vst[g].insert(i);
        swap(S[i], S[k]);
        ans++;
        i--;
        break;
      }
    } else {
      ll r = N - 1 - l;
      ll j = *vst[c].rbegin();
      ll e = seg.get(j, j + 1);
      ll y = idx[j] - e;
      ans += r - y;
      idx[j] = idx[i] = -LOWINF;
      seg.update(j, N, 1);
      vst[c].erase(vst[c].begin());
      vst[c].erase(vst[c].find(*vst[c].rbegin()));
    }
  }
  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define REP(i, n) for (long long i = 0; i < (n); i++)
#define FOR(i, m, n) for (long long i = (m); i < (n); ++i)
#define ALL(obj) (obj).begin(), (obj).end()
#define SPEED                                                                  \
  cin.tie(0);                                                                  \
  ios::sync_with_stdio(false);

template <class T> using V = vector<T>;
template <class T, class U> using P = pair<T, U>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQR = priority_queue<T, vector<T>, greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433;

template <class T> vector<T> multivector(size_t N, T init) {
  return vector<T>(N, init);
}
template <class... T> auto multivector(size_t N, T... t) {
  return vector<decltype(multivector(t...))>(N, multivector(t...));
}
template <class T> void corner(bool flg, T hoge) {
  if (flg) {
    cout << hoge << endl;
    exit(0);
  }
}
template <class T, class U>
ostream &operator<<(ostream &o, const map<T, U> &obj) {
  o << "{";
  for (auto &x : obj)
    o << " {" << x.first << " : " << x.second << "}"
      << ",";
  o << " }";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const set<T> &obj) {
  o << "{";
  for (auto itr = obj.begin(); itr != obj.end(); ++itr)
    o << (itr != obj.begin() ? ", " : "") << *itr;
  o << "}";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const multiset<T> &obj) {
  o << "{";
  for (auto itr = obj.begin(); itr != obj.end(); ++itr)
    o << (itr != obj.begin() ? ", " : "") << *itr;
  o << "}";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &obj) {
  o << "{";
  for (int i = 0; i < (int)obj.size(); ++i)
    o << (i > 0 ? ", " : "") << obj[i];
  o << "}";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const deque<T> &obj) {
  o << "{";
  for (int i = 0; i < (int)obj.size(); ++i)
    o << (i > 0 ? ", " : "") << obj[i];
  o << "}";
  return o;
}
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &obj) {
  o << "{" << obj.first << ", " << obj.second << "}";
  return o;
}
template <template <class tmp> class T, class U>
ostream &operator<<(ostream &o, const T<U> &obj) {
  o << "{";
  for (auto itr = obj.begin(); itr != obj.end(); ++itr)
    o << (itr != obj.begin() ? ", " : "") << *itr;
  o << "}";
  return o;
}
void print(void) { cout << endl; }
template <class Head> void print(Head &&head) {
  cout << head;
  print();
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
  cout << head << " ";
  print(forward<Tail>(tail)...);
}
template <class T> inline void chmax(T &a, const T b) { a = max(a, b); }
template <class T> inline void chmin(T &a, const T b) { a = min(a, b); }
void YN(bool flg) { cout << (flg ? "YES" : "NO") << endl; }
void Yn(bool flg) { cout << (flg ? "Yes" : "No") << endl; }
void yn(bool flg) { cout << (flg ? "yes" : "no") << endl; }

template <class Operator> class LazySegmentTree {
  Operator Op; // Operator 演算子、型、単位元を持つ
  using typeNode = decltype(Op.unitNode); // nodeの型
  using typeLazy = decltype(Op.unitLazy); // lazyの型
  size_t
      length; // セグメント木の最下段の要素の数(vectorの要素の数を超える2べきの数)
  size_t height;         // セグメント木の高さ
  vector<typeNode> node; // node
  vector<typeLazy> lazy; // lazy
  vector<int> width;     // width
public:
  // unitで初期化
  LazySegmentTree(const size_t num) {
    for (length = 1, height = 0; length < num; length *= 2, height++)
      ;
    node.resize(2 * length, Op.unitNode);
    lazy.resize(2 * length, Op.unitLazy);
    width.resize(2 * length, 0);
    for (int i = 0; i < num; ++i)
      node[i + length] = Op.unitNode;
    for (int i = length - 1; i >= 0; --i)
      node[i] = Op.funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
    for (int i = length; i < 2 * length; ++i)
      for (int j = i, k = 1; j && !width[j]; j >>= 1, k <<= 1)
        width[j] = k;
  }

  // //同じinitで初期化
  LazySegmentTree(const size_t num, const typeNode init) {
    for (length = 1, height = 0; length < num; length *= 2, height++)
      ;
    node.resize(2 * length, Op.unitNode);
    lazy.resize(2 * length, Op.unitLazy);
    for (int i = 0; i < num; ++i)
      node[i + length] = init;
    for (int i = length - 1; i >= 0; --i)
      node[i] = Op.funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
    width.resize(2 * length, 0);
    for (int i = length; i < 2 * length; ++i)
      for (int j = i, k = 1; j && !width[j]; j >>= 1, k <<= 1)
        width[j] = k;
  }

  // vectorで初期化
  LazySegmentTree(const vector<typeNode> &vec) {
    for (length = 1, height = 0; length < vec.size(); length *= 2, height++)
      ;
    node.resize(2 * length, Op.unitNode);
    lazy.resize(2 * length, Op.unitLazy);
    for (int i = 0; i < vec.size(); ++i)
      node[i + length] = vec[i];
    for (int i = length - 1; i >= 0; --i)
      node[i] = Op.funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
    width.resize(2 * length, 0);
    for (int i = length; i < 2 * length; ++i)
      for (int j = i, k = 1; j && !width[j]; j >>= 1, k <<= 1)
        width[j] = k;
  }

  void propagate(int k) {
    if (lazy[k] == Op.unitLazy)
      return;
    node[k] = Op.funcMerge(node[k], lazy[k], width[k]);
    if (k < length)
      lazy[2 * k + 0] = Op.funcLazy(lazy[2 * k + 0], lazy[k]);
    if (k < length)
      lazy[2 * k + 1] = Op.funcLazy(lazy[2 * k + 1], lazy[k]);
    lazy[k] = Op.unitLazy;
  }

  // idx : 0-indexed
  void update(int a, int b, typeLazy x) {
    int l = a + length, r = b + length - 1;
    for (int i = height; 0 < i; --i)
      propagate(l >> i), propagate(r >> i);
    for (r++; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = Op.funcLazy(lazy[l], x), propagate(l), l++;
      if (r & 1)
        --r, lazy[r] = Op.funcLazy(lazy[r], x), propagate(r);
    }
    l = a + length, r = b + length - 1;
    while ((l >>= 1), (r >>= 1), l) {
      if (lazy[l] == Op.unitLazy)
        node[l] =
            Op.funcNode(Op.funcMerge(node[(l << 1) + 0], lazy[(l << 1) + 0],
                                     width[(l << 1) + 0]),
                        Op.funcMerge(node[(l << 1) + 1], lazy[(l << 1) + 1],
                                     width[(l << 1) + 1]));
      if (lazy[r] == Op.unitLazy)
        node[r] =
            Op.funcNode(Op.funcMerge(node[(r << 1) + 0], lazy[(r << 1) + 0],
                                     width[(r << 1) + 0]),
                        Op.funcMerge(node[(r << 1) + 1], lazy[(r << 1) + 1],
                                     width[(r << 1) + 1]));
    }
  }

  //[l,r)
  typeNode get(int a, int b) {
    int l = a + length, r = b + length - 1;
    for (int i = height; 0 < i; --i)
      propagate(l >> i), propagate(r >> i);
    typeNode vl = Op.unitNode, vr = Op.unitNode;
    for (r++; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = Op.funcNode(vl, Op.funcMerge(node[l], lazy[l], width[l])), l++;
      if (r & 1)
        r--, vr = Op.funcNode(Op.funcMerge(node[r], lazy[r], width[r]), vr);
    }
    return Op.funcNode(vl, vr);
  }

  void print() {
    // cout << "node" << endl;
    // for(int i = 1,j = 1; i < 2*length; ++i) {
    // 	cout << node[i] << " ";
    // 	if(i==((1<<j)-1) && ++j) cout << endl;
    // }
    // cout << "lazy" << endl;
    // for(int i = 1,j = 1; i < 2*length; ++i) {
    // 	cout << lazy[i] << " ";
    // 	if(i==((1<<j)-1) && ++j) cout << endl;
    // }
    // cout << "width" << endl;
    // for(int i = 1,j = 1; i < 2*length; ++i) {
    // 	cout << width[i] << " ";
    // 	if(i==((1<<j)-1) && ++j) cout << endl;
    // }
    cout << "vector" << endl;
    cout << "{ " << get(0, 1);
    for (int i = 1; i < length; ++i)
      cout << ", " << get(i, i + 1);
    cout << " }" << endl;
  }
};

// node:総和　lazy:加算
template <class typeNode, class typeLazy> struct nodeSumLazyAdd {
  typeNode unitNode = 0;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return l + r; }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return l + r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) { return l + r * len; }
  // LazySegmentTree<nodeSumLazyPlus<ll,ll>> Seg(N,0);
};

// node:最小　lazy:加算
template <class typeNode, class typeLazy> struct nodeMinLazyAdd {
  typeNode unitNode = 1234567890;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return min(l, r); }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return l + r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) { return l + r; }
  // LazySegmentTree<nodeMinLazyAdd<ll,ll>> Seg(N,0);
  // verify https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_H
};

// node:mod和　lazy:mod加算
template <class typeNode, class typeLazy> struct nodeModSumLazyModAdd {
  typeNode unitNode = 0;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return (l + r) % MOD; }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return (l + r) % MOD; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) {
    return (l + (r * len) % MOD) % MOD;
  }
  // LazySegmentTree<nodeModSumLazyModAdd<ll,ll>> dp(N+3,0);
  // verify
  // https://atcoder.jp/contests/code-festival-2018-quala/tasks/code_festival_2018_quala_d
};

// node:最大　lazy:更新
template <class typeNode, class typeLazy> struct nodeMaxLazyUpdate {
  typeNode unitNode = 0;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return max(l, r); }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) {
    return r != 0 ? r * len : l;
  }
  // LazySegmentTree<nodeMaxLazyUpdate<ll,ll>> Seg(N+2,0);
  // verify
  // https://atcoder.jp/contests/nikkei2019-final/tasks/nikkei2019_final_d
};

// node:最小　lazy:更新
template <class typeNode, class typeLazy> struct nodeMinLazyUpdate {
  typeNode unitNode = 12345678910;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) { return min(l, r); }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) {
    return r != 0 ? r * len : l;
  }
  // LazySegmentTree<ll,ll,nodeMinLazyUpdate<ll,ll>> Seg(N,HIGHINF,0);
  // verify
  // https://atcoder.jp/contests/code-festival-2018-final/tasks/code_festival_2018_final_e
};

// node:GCD　lazy:更新
template <class typeNode, class typeLazy> struct nodeGCDLazyUpdate {
  typeNode unitNode = 0;
  typeLazy unitLazy = 0;
  typeNode funcNode(typeNode l, typeNode r) {
    return ((r == 0) ? l : funcNode(r, l % r));
  }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) { return r != 0 ? r : l; }
  // LazySegmentTree<nodeGCDLazyUpdate<ll,ll>> Seg(A);
  // verify https://atcoder.jp/contests/abc125/tasks/abc125_c
};

// node:総和　lazy:更新
template <class typeNode, class typeLazy> struct nodeSumLazyUpdate {
  typeNode unitNode = 0;
  typeLazy unitLazy = -2000;
  typeNode funcNode(typeNode l, typeNode r) { return l + r; }
  typeLazy funcLazy(typeLazy l, typeLazy r) { return r; }
  typeNode funcMerge(typeNode l, typeLazy r, int len) {
    return r != -2000 ? r * len : l;
  }
  // LazySegmentTree<nodeSumLazyUpdate<ll,ll>> Seg(N,0,-2000,0);
  // verify https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_I
};

int main() {
  string S;
  cin >> S;
  vector<int> cnt(26, 0);
  ll N = S.size();
  for (int i = 0; i < N; ++i)
    cnt[S[i] - 'a']++;
  int s = 0;
  for (int i = 0; i < 26; ++i)
    s += cnt[i] % 2;
  corner(s > 1, -1);
  vector<multiset<ll>> vst(26);
  for (int i = 0; i < N; ++i)
    vst[S[i] - 'a'].insert(i);
  vector<ll> idx(N);
  iota(ALL(idx), 0);
  LazySegmentTree<nodeSumLazyAdd<ll, ll>> seg(N, 0);
  ll ans = 0;
  for (int i = 0; i < N; ++i) {
    ll d = seg.get(i, i + 1);
    ll x = idx[i];
    ll l = x - d;
    if (l < 0)
      continue;
    ll c = S[i] - 'a';
    if (vst[c].size() == 1) {
      for (int k = i + 1; k < N; ++k) {
        ll e = seg.get(k, k + 1);
        ll y = idx[k];
        if (y - e < 0)
          continue;
        swap(x, y);
        seg.update(i, i + 1, -d);
        seg.update(i, i + 1, e + 1);
        seg.update(k, k + 1, -e);
        seg.update(k, k + 1, d - 1);
        swap(idx[i], idx[k]);
        ll g = S[k] - 'a';
        vst[c].erase(vst[c].begin());
        vst[g].erase(vst[g].begin());
        vst[c].insert(k);
        vst[g].insert(i);
        swap(S[i], S[k]);
        ans++;
        i--;
        break;
      }
    } else {
      ll r = N - 1 - l;
      ll j = *vst[c].rbegin();
      ll e = seg.get(j, j + 1);
      ll y = idx[j] - e;
      ans += r - y;
      idx[j] = idx[i] = -LOWINF;
      seg.update(j, N, 1);
      vst[c].erase(vst[c].begin());
      vst[c].erase(vst[c].find(*vst[c].rbegin()));
    }
  }
  cout << ans << endl;

  return 0;
}