Problem p03537 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
#define EACH(i, s)                                                             \\
  for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T1, class T2> ostream &operator<<(ostream &s, pair<T1, T2> P) {
  return s << '<' << P.first << ", " << P.second << '>';
}
template <class T> ostream &operator<<(ostream &s, vector<T> P) {
  for (int i = 0; i < P.size(); ++i) {
    if (i > 0) {
      s << " ";
    }
    s << P[i];
  }
  return s;
}
template <class T> ostream &operator<<(ostream &s, vector<vector<T>> P) {
  for (int i = 0; i < P.size(); ++i) {
    s << endl << P[i];
  }
  return s << endl;
}
template <class T1, class T2> ostream &operator<<(ostream &s, map<T1, T2> P) {
  EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; }
  return s << endl;
}

typedef pair<int, int> pint;
const int MAX = 210000;

const int MAX_UF = MAX;
struct UnionFind {
  int size_;
  int par[MAX_UF];
  int rank[MAX_UF];

  UnionFind(int n = 0) {
    size_ = n;
    for (int i = 0; i < n; ++i)
      par[i] = i, rank[i] = 0;
  }
  void init(int n) {
    size_ = n;
    for (int i = 0; i < n; ++i)
      par[i] = i, rank[i] = 0;
  }
  int root(int x) { return par[x] == x ? x : par[x] = root(par[x]); }
  bool same(int x, int y) { return root(x) == root(y); }

  void connect(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y])
        ++rank[x];
    }
  }

  friend ostream &operator<<(ostream &s, UnionFind uf) {
    return s << uf.group();
  }
  vector<vector<int>> group() {
    vector<vector<int>> res;
    vector<bool> fixed(size_, false);
    for (int i = 0; i < size_; ++i) {
      if (!fixed[i]) {
        vector<int> temp;
        for (int j = i; j < size_; ++j) {
          if (same(i, j))
            temp.push_back(j), fixed[j] = true;
        }
        res.push_back(temp);
      }
    }
    return res;
  }
} uf;

string str;
int a[MAX];
int b[MAX];
int N;
pint seg[MAX];

int sum[MAX];

bool solve() {
  int n = str.size() + 1;

  memset(sum, 0, sizeof(sum));
  for (int i = 0; i < n; ++i) {
    int r = uf.root(i);
    sum[r] += b[i];
  }
  for (int i = 0; i < MAX; ++i) {
    if (sum[i] % 26 != 0)
      return false;
  }

  return true;
}

int main() {
  while (cin >> str >> N) {
    int n = str.size() + 1;
    uf.init(n);
    for (int i = 0; i < N; ++i) {
      cin >> seg[i].first >> seg[i].second;
      --seg[i].first;
      uf.connect(seg[i].first, seg[i].second);
    }
    for (int i = 0; i < n / 2; ++i) {
      int j = n - i - 1;
      uf.connect(i, j);
    }

    memset(a, 0, sizeof(a));
    for (int i = 0; i < str.size(); ++i) {
      a[i] = (int)(str[i] - 'a');
    }
    b[0] = a[0];
    for (int i = 0; i < str.size(); ++i) {
      b[i + 1] = a[i + 1] - a[i];
      if (b[i + 1] < 0)
        b[i + 1] += 26;
      // cout << i + 1 << ", " << a[i+1] << ", " << b[i+1] << endl;
    }
    // COUT(uf);

    if (solve())
      puts("YES");
    else
      puts("NO");
  }
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
#define EACH(i, s)                                                             \\
  for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T1, class T2> ostream &operator<<(ostream &s, pair<T1, T2> P) {
  return s << '<' << P.first << ", " << P.second << '>';
}
template <class T> ostream &operator<<(ostream &s, vector<T> P) {
  for (int i = 0; i < P.size(); ++i) {
    if (i > 0) {
      s << " ";
    }
    s << P[i];
  }
  return s;
}
template <class T> ostream &operator<<(ostream &s, vector<vector<T>> P) {
  for (int i = 0; i < P.size(); ++i) {
    s << endl << P[i];
  }
  return s << endl;
}
template <class T1, class T2> ostream &operator<<(ostream &s, map<T1, T2> P) {
  EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; }
  return s << endl;
}

typedef pair<int, int> pint;
const int MAX = 210000;

const int MAX_UF = MAX;
struct UnionFind {
  int size_;
  int par[MAX_UF];
  int rank[MAX_UF];

  UnionFind(int n = 0) {
    size_ = n;
    for (int i = 0; i < n; ++i)
      par[i] = i, rank[i] = 0;
  }
  void init(int n) {
    size_ = n;
    for (int i = 0; i < n; ++i)
      par[i] = i, rank[i] = 0;
  }
  int root(int x) { return par[x] == x ? x : par[x] = root(par[x]); }
  bool same(int x, int y) { return root(x) == root(y); }

  void connect(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y])
        ++rank[x];
    }
  }

  friend ostream &operator<<(ostream &s, UnionFind uf) {
    return s << uf.group();
  }
  vector<vector<int>> group() {
    vector<vector<int>> res;
    vector<bool> fixed(size_, false);
    for (int i = 0; i < size_; ++i) {
      if (!fixed[i]) {
        vector<int> temp;
        for (int j = i; j < size_; ++j) {
          if (same(i, j))
            temp.push_back(j), fixed[j] = true;
        }
        res.push_back(temp);
      }
    }
    return res;
  }
} uf;

string str;
int a[MAX];
int b[MAX];
int N;
pint seg[MAX];

bool solve() {
  int n = str.size() + 1;

  vector<vector<int>> grs = uf.group();
  for (int i = 0; i < grs.size(); ++i) {
    int sum = 0;
    for (auto v : grs[i])
      sum += b[v];
    while (sum < 0)
      sum += 26;
    if (sum % 26 != 0)
      return false;
  }
  return true;
}

int main() {
  while (cin >> str >> N) {
    int n = str.size() + 1;
    uf.init(n);
    for (int i = 0; i < N; ++i) {
      cin >> seg[i].first >> seg[i].second;
      --seg[i].first;
      uf.connect(seg[i].first, seg[i].second);
    }
    for (int i = 0; i < n / 2; ++i) {
      int j = n - i - 1;
      uf.connect(i, j);
    }

    memset(a, 0, sizeof(a));
    for (int i = 0; i < str.size(); ++i) {
      a[i] = (int)(str[i] - 'a');
    }
    b[0] = a[0];
    for (int i = 0; i < str.size(); ++i) {
      b[i + 1] = a[i + 1] - a[i];
      if (b[i + 1] < 0)
        b[i + 1] += 26;
      // cout << i + 1 << ", " << a[i+1] << ", " << b[i+1] << endl;
    }
    // COUT(uf);

    if (solve())
      puts("YES");
    else
      puts("NO");
  }
}