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

#include <cstdio>
#include <vector>
using namespace std;

struct FenwickTree {
  typedef int T;
  vector<T> v;
  void init(int n) { v.assign(n, 0); }
  void add(int i, T x) {
    for (; i < (int)v.size(); i |= i + 1)
      v[i] += x;
  }
  T sum(int i) const { //[0, i)
    T r = 0;
    for (--i; i >= 0; i = (i & (i + 1)) - 1)
      r += v[i];
    return r;
  }
  T sum(int left, int right) const { //[left, right)
    return sum(right) - sum(left);
  }
};

int main() {
  int N;
  while (~scanf("%d", &N)) {
    vector<int> p(N);
    for (int i = 0; i < N; ++i)
      scanf("%d", &p[i]), --p[i];
    int BlockSize = 250, NumBlocks = N / BlockSize + 1;
    vector<vector<long long>> memo(NumBlocks, vector<long long>(N));
    FenwickTree ft;
    for (int bi = 0; bi < NumBlocks; ++bi) {
      vector<long long> &v = memo[bi];
      int i = bi * BlockSize;
      {
        ft.init(N);
        long long sum = 0;
        for (int j = i; j < N; ++j) {
          sum += (j - i) - ft.sum(p[j]);
          v[j] = sum;
          ft.add(p[j], 1);
        }
      }
      {
        ft.init(N);
        long long sum = 0;
        for (int j = i - 1; j >= 0; --j) {
          sum += ft.sum(p[j]);
          v[j] = sum;
          ft.add(p[j], 1);
        }
      }
    }
    ft.init(N);
    int Q;
    scanf("%d", &Q);
    for (int ii = 0; ii < Q; ++ii) {
      int l;
      int r;
      scanf("%d%d", &l, &r), --l, --r;
      int bl = (l + BlockSize - 1) / BlockSize, br = (r - 1) / BlockSize;
      long long ans = 0;
      if (bl > br) {
        for (int i = r; i >= l; --i) {
          ans += ft.sum(p[i]);
          ft.add(p[i], 1);
        }
        for (int i = l; i <= r; ++i)
          ft.add(p[i], -1);
      } else {
        int L = bl * BlockSize, R = br * BlockSize;
        ans += memo[bl][r];
        ans += memo[br][l];
        if (bl < br)
          ans -= memo[bl][R - 1];
        for (int i = R; i <= r; ++i)
          ft.add(p[i], 1);
        for (int i = l; i < L; ++i)
          ans += ft.sum(p[i]);
        for (int i = R; i <= r; ++i)
          ft.add(p[i], -1);
      }
      printf("%lld\\n", ans);
      fflush(stdout);
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
#define rer(i, l, u) for (int(i) = (int)(l); (i) <= (int)(u); ++(i))
#define reu(i, l, u) for (int(i) = (int)(l); (i) < (int)(u); ++(i))
#if defined(_MSC_VER) || __cplusplus > 199711L
#define aut(r, v) auto r = (v)
#else
#define aut(r, v) __typeof(v) r = (v)
#endif
#define each(it, o) for (aut(it, (o).begin()); it != (o).end(); ++it)
#define all(o) (o).begin(), (o).end()
#define pb(x) push_back(x)
#define mp(x, y) make_pair((x), (y))
#define mset(m, v) memset(m, v, sizeof(m))
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
using namespace std;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pair<int, int>> vpii;
typedef long long ll;
template <typename T, typename U> inline void amin(T &x, U y) {
  if (y < x)
    x = y;
}
template <typename T, typename U> inline void amax(T &x, U y) {
  if (x < y)
    x = y;
}

struct FenwickTree {
  typedef int T;
  vector<T> v;
  void init(int n) { v.assign(n, 0); }
  void add(int i, T x) {
    for (; i < (int)v.size(); i |= i + 1)
      v[i] += x;
  }
  T sum(int i) const { //[0, i)
    T r = 0;
    for (--i; i >= 0; i = (i & (i + 1)) - 1)
      r += v[i];
    return r;
  }
  T sum(int left, int right) const { //[left, right)
    return sum(right) - sum(left);
  }
};

int dicts[17][100002];
struct WaveletMatrix {
  typedef unsigned Val;
  int length, bitsize;
  Val maxval;
  vector<int> mids;
  //???????????¢???: (2 * length * sizeof Val) bytes
  //??????: bitsize * length * ??§??????
  void init(const vector<Val> &data) {
    length = data.size();
    maxval = *max_element(data.begin(), data.end());
    for (bitsize = 0; Val(1) << bitsize <= maxval; bitsize++)
      ;
    mids.assign(bitsize, 0);
    vector<Val> datacurrent(data), datanext(length);
    memset(dicts, 0, sizeof dicts);
    for (int bit = 0; bit < bitsize; bit++) {
      int *d = dicts[bit];
      int pos = 0;
      for (int i = 0; i < length; i++) {
        if ((datacurrent[i] >> (bitsize - bit - 1) & 1) == 0) {
          datanext[pos++] = datacurrent[i];
          d[i + 1] = d[i];
        } else {
          d[i + 1] = d[i] + 1;
        }
      }
      mids[bit] = pos;
      for (int i = 0; i < length; i++)
        if ((datacurrent[i] >> (bitsize - bit - 1) & 1) != 0)
          datanext[pos++] = datacurrent[i];
      datacurrent.swap(datanext);
    }
  }
  int rank_lt(Val val, int left, int right) const {
    if (val > maxval) {
      return right - left;
    }
    int lt = 0;
    val <<= 31 - (bitsize - 1);
    for (int bit = 0; bit < bitsize; bit++) {
      if (val >> 31 & 1) {
        int leftcount = dicts[bit][left], rightcount = dicts[bit][right];
        lt += (right - left) - (rightcount - leftcount);
        left = leftcount + mids[bit], right = rightcount + mids[bit];
      } else {
        int leftcount = left - dicts[bit][left],
            rightcount = right - dicts[bit][right];
        left = leftcount, right = rightcount;
      }
      val <<= 1;
    }
    return lt;
  }
  inline int rank_ge(Val val, int left, int right) const {
    return (right - left) - rank_lt(val, left, right);
  }
};

int main() {
  int N;
  while (~scanf("%d", &N)) {
    vector<int> p(N);
    for (int i = 0; i < N; ++i) {
      scanf("%d", &p[i]), --p[i];
    }
    int BlockSize = 300, NumBlocks = N / BlockSize + 1;
    vector<vector<ll>> blockMemo(NumBlocks);
    FenwickTree ft;
    rep(bl, NumBlocks) {
      blockMemo[bl].resize(NumBlocks + 1 - bl);
      int L = bl * BlockSize;
      ft.init(N);
      ll cur = 0;
      for (int r = L + 1, quot = bl, rem = 1; r <= N; ++r) {
        cur += (r - 1 - L) - ft.sum(p[r - 1]);
        ft.add(p[r - 1], 1);
        if (rem == BlockSize) {
          ++quot, rem = 0;
          blockMemo[bl][quot - bl] = cur;
        }
        ++rem;
      }
    }
    WaveletMatrix wm;
    wm.init(vector<unsigned>(all(p)));
    int Q;
    scanf("%d", &Q);
    rep(ii, Q) {
      int l;
      int r;
      scanf("%d%d", &l, &r), --l, --r;
      int bl = l / BlockSize;
      int br = r / BlockSize;
      ll ans = 0;
      if (bl == br) {
        for (int i = l; i <= r; ++i)
          ans += wm.rank_ge(p[i], l, i);
      } else {
        ans += blockMemo[bl + 1][br - bl - 1];
        int L = (bl + 1) * BlockSize, R = br * BlockSize;
        for (int i = l; i < L; ++i)
          ans += wm.rank_lt(p[i], i + 1, r + 1);
        for (int i = R; i <= r; ++i)
          ans += wm.rank_ge(p[i], L, i);
      }
      printf("%lld\\n", ans);
      fflush(stdout);
    }
  }
  return 0;
}