Problem:
H: われわれの努力について - About Our Effort -
問題
※この問題はおまけの問題と捉えていただけるとありがたく、
できれば先に他の問題のほうをお楽しみいただければと思っておりまして，ですので他の問題を通し終えて暇になり，かつその暇を
このコンテストで潰そうという気になってくれた方に挑戦していただければと思います。
D問題のクエリが遅くてすみませんでした。
しかし我々といたしましても決してただ怠慢をしていたわけではないのです。
私たちなりに努力したのです。
その努力の片鱗を味わっていただくため、このような問題を出題した次第であります。
問題: D問題のサーバー側の処理をするプログラムを作成せよ。
なおこの問題は本当にD問題の要求を満たすプログラムを作成することが目標ということですので、言語による向き/不向きなどは一切考慮いたしませんのであしからず。最速実行速度を達成された方はもれなくAOJに収録される際にジャッジプログラムとして採用される可能性がありますのでぜひ挑戦下さい。
入力形式
入力は以下の形式で与えられる。
N
p_1
...
p_N
Q
l_1
r_1
...
l_Q
r_Q
1行目では順列
p
の長さ
N
が与えられる。2行目では順列
p
を表す
N
個の整数が空白区切りで与えられる。3行目ではクエリの数を表す整数
Q
が与えられる。続く
Q
行の
i
行目は空白区切りの2つの整数
l_i
,
r_i
からなり、クエリが区間
[l_i, r_i]
のコンプレックス度を聞くものであることを表す。
入力は以下の制約を満たす。
1 \≤ N \≤ 100,000
1 \≤ p_i \≤ N
,
p_i \neq p_j (i \neq j)
1 \≤ Q \≤ 200,000
1 \≤ l_i \≤ r_i \≤ N
出力形式
Q
個の各クエリ
i
に関して、
p
の区間
[l_i, r_i]
のコンプレックス度を
i
行目に出力せよ。ただし、
p
の区間
[l_i, r_i]
のコンプレックス度とは、
(\{ (i, j) | p_i > p_j
{\rm for}
l \≤ i<j \≤ r \}の要素数)
と定義される。
入力例1
4
4 1 3 2
2
1 3
2 4
出力例1
2
1
入力例2
1
1
1
1 1
出力例2
0

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

#define SIZE 200000
#define SQ 300
#define LLINF 100000000000000

struct BIT {
  vector<int> data;

  BIT(int n): data(n + 2, 0) {};

  void add(int k, int x) {
    k++;
    while (k <= data.size() - 2) {
      data[k] += x;
      k += k & -k;
    }
  }

  int query(int k) {
    int rec = 0;
    while (k > 0) {
      rec += data[k];
      k -= k & (-k);
    }
    return rec;
  }

  int query(int a, int b) {
    return query(b) - query(a);
  }
};

int N, P[SIZE];
ll ans[SIZE];

int main() {
  scanf("%d", &N);

  for (int i = 0; i < N; i++) {
    scanf("%d", P + i);
    P[i]--;
  }

  int Q;

  vector<pair<pair<int, int>, pair<int, int>>> queries;

  scanf("%d", &Q);

  for (int i = 0; i < Q; i++) {
    int l, r;
    scanf("%d%d", &l, &r);
    l--;
    int t = l / SQ;

    queries.push_back({{t, r}, {l, i}});
  }

  sort(queries.begin(), queries.end());

  BIT bit(N);
  int L = 0, R = 0;
  ll cur = 0;

  for (int i = 0; i < Q; i++) {
    int idx = queries[i].second.second;
    int l = queries[i].second.first;
    int r = queries[i].first.second;

    while (R < r) {
      int p = P[R];
      cur += bit.query(p, N);
      bit.add(p, 1);
      R++;
    }
    while (L < l) {
      int p = P[L];
      cur -= bit.query(p);
      bit.add(p, -1);
      L++;
    }
    while (l < L) {
      int p = P[L - 1];
      cur += bit.query(p);
      L--;
      bit.add(p, 1);
    }
    while (r < R) {
      int p = P[R - 1];
      bit.add(p, -1);
      cur -= bit.query(p, N);
      R--;
    }

    ans[idx] = cur;
  }

  for (int i = 0; i < Q; i++) {
    printf("%lld\n", ans[i]);
  }

  return 0;
}
accuracy: 1
time_ms: 1460
memory_kb: 8512
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
#define all(a) begin(a),end(a)


const ll MAX = 1000001;
ll bit[MAX];
ll sum_all = 0;
void add(ll k, ll x){
    sum_all += x;
    for(; k < MAX; k += k & -k) bit[k] += x;
}
ll low(ll k){ // (0, k]
    ll ans = 0;
    for(; k; k -= k & -k) ans += bit[k];
    return ans;
}
ll high(ll k){ // (k, MAX]
    return sum_all - low(k);
}
int main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    ll n;
    cin >> n;
    vector<ll> p(n);
    for(ll& x : p) cin >> x;
    ll q;
    cin >> q;
    vector<pll> query(q);
    for(auto& [l, r] : query){
        cin >> l >> r;
        l--;
    }
    const ll sq = sqrt(n);
    vector<ll> idx(q);
    iota(all(idx), 0);
    sort(all(idx), [&](ll x, ll y){
        const auto [l1, r1] = query[x];
        const auto [l2, r2] = query[y];
        if(l1 / sq == l2 / sq){
            return r1 < r2;
        }
        return l1 < l2;
    });
    vector<ll> ans(q);
    ll L = 0, R = 0, cnt = 0;
    for(ll i : idx){
        const auto [l, r] = query[i];
        while(R < r){
            cnt += high(p[R]);
            add(p[R], 1);
            R++;
        }
        while(L > l){
            L--;
            cnt += low(p[L]);
            add(p[L], 1);
        }
        while(R > r){
            R--;
            add(p[R], -1);
            cnt -= high(p[R]);
        }
        while(L < l){
            add(p[L], -1);
            cnt -= low(p[L]);
            L++;
        }
        ans[i] = cnt;
    }
    for(ll i : ans) cout << i << '\n';
}
accuracy: 1
time_ms: 1580
memory_kb: 15128
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
#define all(a) begin(a),end(a)


const ll MAX = 1000001;
ll bit[MAX];
ll sum_all = 0;
void add(ll k, ll x){
    sum_all += x;
    for(; k < MAX; k += k & -k) bit[k] += x;
}
ll low(ll k){ // (0, k]
    ll ans = 0;
    for(; k; k -= k & -k) ans += bit[k];
    return ans;
}
ll high(ll k){ // (k, MAX]
    return sum_all - low(k);
}
int main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    ll n;
    cin >> n;
    vector<ll> p(n);
    for(ll& x : p) cin >> x;
    ll q;
    cin >> q;
    vector<pll> query(q);
    for(auto& [l, r] : query){
        cin >> l >> r;
        l--;
    }
    const ll sq = sqrt(n);
    vector<ll> idx(q);
    iota(all(idx), 0);
    sort(all(idx), [&](ll x, ll y){
        const auto [l1, r1] = query[x];
        const auto [l2, r2] = query[y];
        if(l1 / sq == l2 / sq){
            if(l1 / sq & 1) return r1 > r2;
            else return r1 < r2;
        }
        return l1 < l2;
    });
    vector<ll> ans(q);
    ll L = 0, R = 0, cnt = 0;
    for(ll i : idx){
        const auto [l, r] = query[i];
        while(R < r){
            cnt += high(p[R]);
            add(p[R], 1);
            R++;
        }
        while(L > l){
            L--;
            cnt += low(p[L]);
            add(p[L], 1);
        }
        while(R > r){
            R--;
            add(p[R], -1);
            cnt -= high(p[R]);
        }
        while(L < l){
            add(p[L], -1);
            cnt -= low(p[L]);
            L++;
        }
        ans[i] = cnt;
    }
    for(ll i : ans) cout << i << '\n';
}
accuracy: 1
time_ms: 1090
memory_kb: 15156
final_rank: 1

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using u64 = uint_fast64_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(),(x).end()
constexpr char ln =  '\n';
constexpr long long MOD = 1000000007;
//constexpr long long MOD = 998244353;
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) { if (a < b) { a = b; return true;} return false; }
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) { if (a > b) { a = b; return true;} return false; }
inline int popcount(int x) {return __builtin_popcount(x);}
inline int popcount(long long x) {return __builtin_popcountll(x);}
void print() { cout << "\n"; }
template<class T, class... Args>
void print(const T &x, const Args &... args) {
    cout << x << " ";
    print(args...);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
struct BinaryIndexedTree {
    int N;
    vector<T> data;

    BinaryIndexedTree(){}
    BinaryIndexedTree(int N) : N(N), data(N+1,0) {}

    // [0,k) (0-indexed) a[0] + … + a[k-1]
    T sum(int k) {
        T ret = 0;
        for(; k > 0; k -= k & -k) ret += data[k];
        return ret;
    }

    // [l,r) (0-indexed) a[l] + …　+ a[r-1]
    T sum(int l, int r) {
        if (l >= r) return 0;
        T vl = sum(l);
        T vr = sum(r);
        return vr - vl;
    }
    // (0-indexed) a[k] += x;
    void add(int k, T x) {
        for(++k; k <= N; k += k & -k) data[k] += x;
    }

    // (0-indexed)
    int lowerbound(T x) {
        int k = 1;
        int ret = 0;
        while ((k<<1) <= N) k <<= 1;
        while (k) {
            if (ret + k <= N && data[ret+k] < x) {
                x -= data[ret+k];
                ret += k;
            }
            k >>= 1;
        }
        return ret;
    }

    // (0-indexed)
    int upperbound(T x) {return lowerbound(x+1);}
};

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    vector<int> p(N);
    rep(i,N) {
        cin >> p[i];
        --p[i];
    }

    int Q; cin >> Q;
    vector<int> L(Q),R(Q);
    rep(i,Q) {
        cin >> L[i] >> R[i];
        --L[i];
    }
    const int B = 500;
    vector<int> idx(Q);
    iota(all(idx),0);
    sort(all(idx),[&](int i, int j){
        if (L[i]/B==L[j]/B) return R[i] < R[j];
        return L[i] < L[j]; 
    });
    BinaryIndexedTree<int> BIT(N);
    vector<ll> ans(Q);
    int nl = 0, nr = 0;
    ll val = 0;
    rep(i,Q) {
        int u = idx[i];
        while (nl > L[u]) {
            nl--;
            val += BIT.sum(p[nl]);
            BIT.add(p[nl],1);
        }
        while (nr < R[u]) {
            val += BIT.sum(p[nr]+1,N);
            BIT.add(p[nr],1);
            nr++;
        }
        while (nl < L[u]) {
            BIT.add(p[nl],-1);
            val -= BIT.sum(p[nl]);
            nl++;
        }
        while (nr > R[u]) {
            nr--;
            BIT.add(p[nr],-1);
            val -= BIT.sum(p[nr]+1,N);
        }
        ans[u] = val;
    }

    for (auto i : ans) cout << i << ln;
}
accuracy: 1
time_ms: 1390
memory_kb: 7644
final_rank: 2

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using u64 = uint_fast64_t;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(),(x).end()
constexpr char ln =  '\n';
constexpr long long MOD = 1000000007;
//constexpr long long MOD = 998244353;
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) { if (a < b) { a = b; return true;} return false; }
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) { if (a > b) { a = b; return true;} return false; }
inline int popcount(int x) {return __builtin_popcount(x);}
inline int popcount(long long x) {return __builtin_popcountll(x);}
void print() { cout << "\n"; }
template<class T, class... Args>
void print(const T &x, const Args &... args) {
    cout << x << " ";
    print(args...);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
struct BinaryIndexedTree {
    int N;
    vector<T> data;

    BinaryIndexedTree(){}
    BinaryIndexedTree(int N) : N(N), data(N+1,0) {}

    // [0,k) (0-indexed) a[0] + … + a[k-1]
    T sum(int k) {
        T ret = 0;
        for(; k > 0; k -= k & -k) ret += data[k];
        return ret;
    }

    // [l,r) (0-indexed) a[l] + …　+ a[r-1]
    T sum(int l, int r) {
        if (l >= r) return 0;
        T vl = sum(l);
        T vr = sum(r);
        return vr - vl;
    }
    // (0-indexed) a[k] += x;
    void add(int k, T x) {
        for(++k; k <= N; k += k & -k) data[k] += x;
    }

    // (0-indexed)
    int lowerbound(T x) {
        int k = 1;
        int ret = 0;
        while ((k<<1) <= N) k <<= 1;
        while (k) {
            if (ret + k <= N && data[ret+k] < x) {
                x -= data[ret+k];
                ret += k;
            }
            k >>= 1;
        }
        return ret;
    }

    // (0-indexed)
    int upperbound(T x) {return lowerbound(x+1);}
};

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N; cin >> N;
    vector<int> p(N);
    rep(i,N) {
        cin >> p[i];
        --p[i];
    }

    int Q; cin >> Q;
    vector<int> L(Q),R(Q);
    rep(i,Q) {
        cin >> L[i] >> R[i];
        --L[i];
    }
    const int B = 500;
    vector<int> idx(Q);
    iota(all(idx),0);
    sort(all(idx),[&](int i, int j){
        if (L[i]/B==L[j]/B) return R[i] < R[j];
        return L[i] < L[j]; 
    });
    BinaryIndexedTree<int> BIT(N);
    vector<int> ans(Q);
    int nl = 0, nr = 0;
    ll val = 0;
    rep(i,Q) {
        int u = idx[i];
        while (nl > L[u]) {
            nl--;
            val += BIT.sum(p[nl]);
            BIT.add(p[nl],1);
        }
        while (nr < R[u]) {
            val += BIT.sum(p[nr]+1,N);
            BIT.add(p[nr],1);
            nr++;
        }
        while (nl < L[u]) {
            BIT.add(p[nl],-1);
            val -= BIT.sum(p[nl]);
            nl++;
        }
        while (nr > R[u]) {
            nr--;
            BIT.add(p[nr],-1);
            val -= BIT.sum(p[nr]+1,N);
        }
        ans[u] = val;
    }

    for (auto i : ans) cout << i << ln;
}
accuracy: 0.6176470588235294
time_ms: 1260
memory_kb: 6592
final_rank: 17

code_snippet: #include <cstdio>
#include <vector>
#include <algorithm>
#include <functional>
#include <tuple>
#include <utility>
using namespace std;
using ll = long long int;

const int B = 500;

// @category セグメント木 (Segment Tree)
// @title セグメント木 (Segment Tree)
// 抽象 SegmentTree (0-indexed・一点更新・区間取得)
template <typename MonoidType>
struct SegmentTree {
    using Function = function< MonoidType(MonoidType, MonoidType) >;

    // node, identity element
    int n;
    vector<MonoidType> node;
    MonoidType E0;

    // update / combine function
    Function upd_f, cmb_f;

    void build(int m, vector<MonoidType> v = vector<MonoidType>()) {
        if(v != vector<MonoidType>()) m = v.size();
        n = 1; while(n < m) n *= 2;

        node = vector<MonoidType>(2*n-1, E0);
        if(v != vector<MonoidType>()) {
            for(int i=0; i<m; i++) {
                node[n-1+i] = v[i];
            }
            for(int i=n-2; i>=0; i--) {
                node[i] = cmb_f(node[2*i+1], node[2*i+2]);
            }
        }
    }

    // initialize
    SegmentTree() {}
    SegmentTree(int n_, MonoidType E0_,
                Function upd_f_, Function cmb_f_,
                vector<MonoidType> v = vector<MonoidType>()) :
        E0(E0_), upd_f(upd_f_), cmb_f(cmb_f_) {
        build(n_, v);
    }

    // update k-th element (applied value: x)
    void update(int k, MonoidType x) {
        k += n - 1;
        node[k] = upd_f(node[k], x);
        while(k > 0) {
            k = (k - 1) / 2;
            node[k] = cmb_f(node[2*k+1], node[2*k+2]);
        }
    }

    // range query for [a, b)
    // 非再帰のアイデア: http://d.hatena.ne.jp/komiyam/20131202/1385992406
    MonoidType query(int a, int b) {
        MonoidType vl = E0, vr = E0;
        for(int l=a+n, r=b+n; l<r; l>>=1, r>>=1) {
            if(l & 1) vl = cmb_f(vl, node[(l++)-1]);
            if(r & 1) vr = cmb_f(node[(--r)-1], vr);
        }
        return cmb_f(vl, vr);
    }
};

int main() {
    int N; scanf("%d", &N);
    vector<int> P(N);
    for(int i=0; i<N; i++) scanf("%d", &P[i]), P[i]--;

    vector< vector< tuple<int, int, int> > > segs(B);
    int Q; scanf("%d", &Q);
    for(int i=0; i<Q; i++) {
        int l, r; scanf("%d%d", &l, &r); l--;
        int b = l / B;
        segs[b].emplace_back(l, r, i);
    }

    for(int i=0; i<B; i++) {
        sort(segs[i].begin(), segs[i].end(), [](auto x, auto y) {
                return get<1>(x) < get<1>(y);
            });
    }

    SegmentTree<int> seg(N, 0,
                         [](int a, int b) { return a + b; },
                         [](int a, int b) { return a + b; });
    ll sum = 0, pl = 0, pr = 0;
    auto add_l = [&]() {
        sum += seg.query(0, P[--pl]);
        seg.update(P[pl], +1);
    };
    auto add_r = [&]() {
        sum += seg.query(P[pr] + 1, N);
        seg.update(P[pr++], +1);
    };
    auto del_l = [&]() {
        sum -= seg.query(0, P[pl]);
        seg.update(P[pl++], -1);
    };
    auto del_r = [&]() {
        sum += seg.query(P[--pr] + 1, N);
        seg.update(P[pr], -1);
    };

    vector<ll> ans(Q);
    for(int i=0; i<B; i++) {
        for(auto e : segs[i]) {
            int l, r, k; tie(l, r, k) = e;
            while(pl < l) del_l();
            while(pl > l) add_l();
            while(pr < r) add_r();
            while(pr > r) del_r();
            ans[k] = sum;
        }
    }
    for(int i=0; i<Q; i++) printf("%lld\n", ans[i]);
    return 0;
}
accuracy: 0.3235294117647059
time_ms: 50
memory_kb: 2780
final_rank: 20

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long Int;

const int MAX_N = 100000;
const int SQRT_N = 400;

int N;
int A[MAX_N];
int P[MAX_N+1];
int E[MAX_N+1][SQRT_N+1], F[SQRT_N+1][MAX_N+1];
int G[MAX_N+1], H[MAX_N+1];
Int X[SQRT_N+1][SQRT_N+1];
int pre[SQRT_N], suf[SQRT_N];
int B_size, B_num;

//Fenwick Tree
int bit_size;
int bit[MAX_N+1];

//note that we maintain bit[1..n]
inline void init(int n){
  bit_size = n;
  memset(bit,0,sizeof(bit));
}

//add x to the i-th element
inline void inc(int i){
  while(i <= bit_size){
    bit[i]++;
    i += i & -i;
  }
}

//sum of [1..i]
inline int sum(int i){
  int res = 0;
  while(i > 0){
    res += bit[i];
    i -= i & -i;
  }
  return res;
}

//sum of [l..r]
inline int partial_sum(int l, int r){ return sum(r) - sum(l-1); }

inline void preprocess(void) {
  //Set B_size and B_num
  B_size = sqrt(N);
  //B_size = 400;
  B_num = (N + B_size-1) / B_size;

  //Step 1: make E and F
  for(int k=0;k<B_num;k++) {
    int l = k*B_size, r = min( (k+1)*B_size, N);

    memset(P,0,sizeof(P));
    for(int i=l;i<r;i++) {
      P[A[i]]++;
    }

    for(int i=0;i<N-1;i++) {
      P[i+1] += P[i];
    }

    //fill E
    int backward = 0;
    for(int i=l-1;i>=0;i--){
      backward += P[A[i]];
      E[i][k] = backward;
    }

    memset(P,0,sizeof(P));
    for(int i=l;i<r;i++) {
      P[A[i]]++;
    }

    for(int i=0;i<N-1;i++) {
      P[N-i-2] += P[N-i-1];
    }

    //fill F
    int forward = 0;
    for(int i=r;i<N;i++){
      forward += P[A[i]];
      F[k][i] = forward;
    }
  }

  //Step2-1: make G
  init(N);
  int suf_inv = 0;
  for(int i=N-1;i>=0;i--){
    suf_inv += partial_sum(1,A[i]+1);
    inc(A[i]+1);
    G[i] = suf_inv;

    if(i%B_size == 0){
      init(N);
      suf_inv = 0;
    }
  }

  //Step2-2: make H
  int pre_inv = 0;
  for(int i=0;i<N;i++){
    if(i%B_size == 0){
      init(N);
      pre_inv = 0;
    }
    pre_inv += partial_sum(A[i]+1, N);
    inc(A[i]+1);
    H[i] = pre_inv;
  }

  //Step3: make X
  for(int L=0;L<B_num;L++){
    Int inv = 0;
    for(int R=L;R<B_num;R++){
      inv += G[R*B_size];
      inv += E[L*B_size][R];
      X[L][R+1] = inv;
    }
  }

  //Step4: update E and F
  for(int k=0;k<B_num;k++){
    for(int i=0;i<k*B_size;i++){
      E[i][k] -= E[(i+B_size-1)/B_size*B_size][k];
    }
    for(int i=N-1;i>=k*B_size;i--){
      F[k][i] -= F[k][(i+1)/B_size*B_size-1];
    }
  }

  for(int i=0;i<N;i++){
    for(int k=0;k<B_num-1;k++){
      E[i][k+1] += E[i][k];
      F[k+1][i] += F[k][i];
    }
  }
}

inline void answer_query(int l, int r){
  l--;
  int L = (l+B_size-1)/B_size, R = r/B_size;
  int Ll = l, Lr = L*B_size, Rl = R*B_size, Rr = r;

  //l and r are in the same block
  if(L>=R){
    Int inv = 0;

    init(N);
    for(int i=l;i<r;i++){
      inv += partial_sum(A[i]+1, N);
      inc(A[i]+1);
    }

    printf("%lld\n", inv);
    return;
  }

  //l and r are in different blocks
  Int inv = 0;

  //inversion in consecutive blcoks
  inv += X[L][R];

  //inversion between prefix/suffix and consecutive blocks
  inv += E[l][R-1] - (L==0?0:E[l][L-1]);
  inv += F[R-1][r-1] - (L==0?0:F[L-1][r-1]);

  //inversion in prefix/suffix
  if(Ll<Lr) inv += G[l];
  if(Rl<Rr) inv += H[r-1];

  //inversion between prefix and suffix (using radix sort)

  int pn = Lr-Ll;
  for(int i=Ll;i<Lr;i++) {
    pre[i-Ll] = A[i];
  }
  sort(pre,pre+pn);
  
  int sn = Rr-Rl;
  for(int i=Rl;i<Rr;i++) {
    suf[i-Rl] = A[i];
  }
  sort(suf,suf+sn);
  
  int id_p = 0, id_s = 0;
  while(id_p<pn) {
    if(id_s == sn) {
      id_p++;
      inv += id_s;
    } else {
      if(pre[id_p] < suf[id_s]) {
	id_p++;
	inv += id_s;
      } else {
	id_s++;
      }
    }
  }

  printf("%lld\n", inv);
}

int main(){
  scanf("%d",&N);

  for(int i=0;i<N;i++) {
    scanf("%d", A+i); A[i]--;
  }

  preprocess();

  int Q;
  scanf("%d",&Q);

  while(Q--){
    int l,r;
    scanf("%d%d",&l,&r);

    answer_query(l,r);
  }
}
accuracy: 1
time_ms: 2240
memory_kb: 286704
final_rank: 11

code_snippet: #include<bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define dbg(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

ll bit[131072];
ll sum(int i){
	ll res = 0;
	for(; i; i -= i & -i) res += bit[i];
	return res;
}
void add(int i, int x){
	for(; i < 131072; i += i & -i) bit[i] += x;
}

const int B = 500;
int n, p[100000];
ll ans[200000];

int main(){
	cin.tie(0); cin.sync_with_stdio(0);
	cin >> n;
	rep(i, n) cin >> p[i];
	int q; cin >> q;
	
	vector<pair<pi, pi>> v; //l/B, r, l
	rep(i, q){
		int l, r; cin >> l >> r; l--;
		v.pb(mp(mp(l / B, r), mp(l, i)));
	}
	int cnt = 0;
	sort(all(v));
	int L = 0, R = 0; ll res = 0;
	for(auto &i: v){
		int r = i.first.second, l = i.second.first;
		while(R < r) { assert(L <= R); res += R - L - sum(p[R]);         add(p[R++], 1); }
		while(L > l) { assert(L <= R); res += sum(p[--L]);               add(p[L], 1); }
		while(L < l) { assert(L < R); res -= sum(p[L]) - 1;             add(p[L++], -1); }
		while(R > r) { assert(L < R); res -= R - L; res += sum(p[--R]); add(p[R], -1); }
		ans[i.second.second] = res;
	}
	rep(i, q) printf("%lld\n", ans[i]);
	
	return 0;
}
accuracy: 1
time_ms: 1460
memory_kb: 8972
final_rank: 4

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <map>
#include <utility>
#include <algorithm>
using namespace std;
 
#define B 317
 
typedef long long int LLI;
#define int long long int
 
typedef pair<string, int> Pair;
typedef pair<int, int> Seg;
typedef pair<Seg, pair<int,int> > Data;
 
int size;
int T;
int n;
int m;
LLI cur;
LLI ans[200005];
LLI BIT2[100005];
vector<int> list_str;
vector<int> sorted_str;
int myrank[100010];
vector<Data> queries;
 
bool cmp_query(const Data &d1, const Data &d2) {
    int l1 = d1.first.first;
    int r1 = d1.first.second;
    int l2 = d2.first.first;
    int r2 = d2.first.second;
    
    if (l1/B != l2/B) return l1/B < l2/B;
    return r1 < r2;
}
 
void update(LLI *BIT, int k, LLI x) {
  k++;
    while (k <= n) {
        BIT[k] += x;
        k += k&-k;
    }
}
 
LLI getsum(LLI *BIT, int k) {
  k++;
    LLI ret = 0;
    while (k > 0) {
        ret += BIT[k];
        k -= k&-k;
    }
    return ret;
}
 
void append_end(int x) {
    int &ss = list_str[x];
    int idx = myrank[ss];
    cur += getsum(BIT2, n-1) - getsum(BIT2, idx); // (idx,n-1]
    update(BIT2, idx, 1);
}
void append_front(int x) {
    int &ss = list_str[x];
    int idx = myrank[ss];
    cur += getsum(BIT2, idx-1);
    update(BIT2, idx, 1);
}
void remove_end(int x) {
    int &ss = list_str[x];
    int idx = myrank[ss];
    cur -= getsum(BIT2, n-1) - getsum(BIT2, idx); // (idx,n-1]
    update(BIT2, idx, -1);
}
void remove_front(int x) {
    int &ss = list_str[x];
    int idx = myrank[ss];
    cur -= getsum(BIT2,idx-1);
    update(BIT2, idx, -1);
}
 
signed main() {
    ios_base::sync_with_stdio(false);
 
    //cin >> T;
    while (1) {
        cin >> n;
        size = 1;
        fill(BIT2, BIT2+n+1, 0ll);
 
        list_str.clear();
        sorted_str.clear();
        for (int i=0; i<n; i++) {
          int s;
          cin >> s;
          list_str.push_back(s);
          sorted_str.push_back(s);
        }
        sort(sorted_str.begin(), sorted_str.end());
        for (int i=0; i<n; i++) {
            myrank[sorted_str[i]] = i;
        }
 
        queries.clear();
        cin >> m;
        for(int j = 0 ; j < m ; j++){
            int l, r,k;
            cin >> l >> r;
            --l;
            --r;
            queries.push_back(Data(Seg(l, r), {j,j}));
      }
      
        sort(queries.begin(), queries.end(), cmp_query);
        cur = 0;
        int a = 0;
        int b = -1;
        for (int i=0; i<queries.size(); i++) {
            int l = queries[i].first.first;
            int r = queries[i].first.second;
            int idx = queries[i].second.second;
            int k = queries[i].second.first;
            while (b < r) append_end(++b);
            while (l < a) append_front(--a);
            while (a < l) remove_front(a++);
            while (r < b) remove_end(b--);
            ans[idx] = cur;
        }
 
        for (int i=0; i<m; i++) {
            cout << ans[i] << endl;
        }
        break;
    }
}
accuracy: 1
time_ms: 1850
memory_kb: 14412
final_rank: 6

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <map>
#include <utility>
#include <algorithm>
using namespace std;
 
#define B 317
 
typedef long long int LLI;
#define int long long int
 
typedef pair<string, int> Pair;
typedef pair<int, int> Seg;
typedef pair<Seg, pair<int,int> > Data;
 
int size;
int T;
int n;
int m;
LLI cur;
LLI ans[100005];
LLI BIT2[100005];
vector<int> list_str;
vector<int> sorted_str;
int myrank[100010];
vector<Data> queries;
 
bool cmp_query(const Data &d1, const Data &d2) {
    int l1 = d1.first.first;
    int r1 = d1.first.second;
    int l2 = d2.first.first;
    int r2 = d2.first.second;
    
    if (l1/B != l2/B) return l1/B < l2/B;
    return r1 < r2;
}
 
void update(LLI *BIT, int k, LLI x) {
  k++;
    while (k <= n) {
        BIT[k] += x;
        k += k&-k;
    }
}
 
LLI getsum(LLI *BIT, int k) {
  k++;
    LLI ret = 0;
    while (k > 0) {
        ret += BIT[k];
        k -= k&-k;
    }
    return ret;
}
 
void append_end(int x) {
    int &ss = list_str[x];
    int idx = myrank[ss];
    cur += getsum(BIT2, n-1) - getsum(BIT2, idx); // (idx,n-1]
    update(BIT2, idx, 1);
}
void append_front(int x) {
    int &ss = list_str[x];
    int idx = myrank[ss];
    cur += getsum(BIT2, idx-1);
    update(BIT2, idx, 1);
}
void remove_end(int x) {
    int &ss = list_str[x];
    int idx = myrank[ss];
    cur -= getsum(BIT2, n-1) - getsum(BIT2, idx); // (idx,n-1]
    update(BIT2, idx, -1);
}
void remove_front(int x) {
    int &ss = list_str[x];
    int idx = myrank[ss];
    cur -= getsum(BIT2,idx-1);
    update(BIT2, idx, -1);
}
 
signed main() {
    ios_base::sync_with_stdio(false);
 
    //cin >> T;
    while (1) {
        cin >> n;
        size = 1;
        fill(BIT2, BIT2+n+1, 0ll);
 
        list_str.clear();
        sorted_str.clear();
        for (int i=0; i<n; i++) {
          int s;
          cin >> s;
          list_str.push_back(s);
          sorted_str.push_back(s);
        }
        sort(sorted_str.begin(), sorted_str.end());
        for (int i=0; i<n; i++) {
            myrank[sorted_str[i]] = i;
        }
 
        queries.clear();
        cin >> m;
        for(int j = 0 ; j < m ; j++){
            int l, r,k;
            cin >> l >> r;
            --l;
            --r;
            queries.push_back(Data(Seg(l, r), {j,j}));
      }
      
        sort(queries.begin(), queries.end(), cmp_query);
        cur = 0;
        int a = 0;
        int b = -1;
        for (int i=0; i<queries.size(); i++) {
            int l = queries[i].first.first;
            int r = queries[i].first.second;
            int idx = queries[i].second.second;
            int k = queries[i].second.first;
            while (b < r) append_end(++b);
            while (l < a) append_front(--a);
            while (a < l) remove_front(a++);
            while (r < b) remove_end(b--);
            ans[idx] = cur;
        }
 
        for (int i=0; i<m; i++) {
            cout << ans[i] << endl;
        }
        break;
    }
}
accuracy: 0.6176470588235294
time_ms: 60
memory_kb: 14396
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;
#define REP(i,n) for(ll i=0;i<n;++i)
#define REPR(i,n) for(ll i=1;i<n;++i)
#define FOR(i,a,b) for(ll i=a;i<b;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define MOD (ll)(1e9+7)
#define ADD(a,b) a=((a)+(b))%MOD
#define FIX(a) ((a)%MOD+MOD)%MOD

// http://hos.ac/slides/20140319_bit.pdf
struct BIT{
  int n;
  vl dat;
  BIT(){}
  BIT(int n):n(n){dat.assign(n,0);}
  BIT(int n, ll arr[]){
    dat.assign(n,0);
    REP(i,n-1){
      dat[i]+=arr[i];
      dat[i|(i+1)]+=dat[i];
    }
  }
  BIT(BIT &past):n(past.n),dat(past.dat){}
  // 0-indexed
  void add(int pos, ll val){for(int x=pos;x<n;x|=x+1)dat[x]+=val;}
  // [0...pos]
  ll sum(int pos){
    ll ret = 0;
    for(int x=pos;x>=0;x=(x&(x+1))-1)ret+=dat[x];
    return ret;
  }
  ll all(){
    return sum(n-1);
  }
  // [pos...n-1]
  ll revsum(int pos){
    return all()-sum(pos-1);
  }
};

// http://japl.pl/contest/ijpc/1/reviews/training.html

int n;
ll p[100001];
int sqrtn;
ll s[317][317];
BIT f[317];

int main(){
  scanf("%d",&n);
  REP(i,n)scanf("%d",p+i);
  // ???????????´
  sqrtn = 1;
  while(sqrtn*sqrtn<n)++sqrtn;
  FOR(i,n,sqrtn*sqrtn)p[i]=n;
  n = sqrtn*sqrtn;
  // ?????±??????????????±?????? sum
  REP(i,sqrtn){
    BIT bit(n+1);
    ll ans = 0;
    FOR(j,i,sqrtn){
      // update bit
      REP(k,sqrtn){
        ll val = p[j*sqrtn + k];
        ans += bit.revsum(val+1);
        bit.add(val,1);
      }
      s[i][j] = ans;
    }
  }
  // ????????????
  {
    BIT bit(n+1);
    REP(i,sqrtn){
      REP(j,sqrtn)bit.add(p[i*sqrtn+j],1);
      f[i] = BIT(bit);
    }
  }
  // answer
  int q;
  scanf("%d",&q);
  BIT bit(n+1);  // ??????n????´?????????£?¨????????????¨O(NQ)????????§????????????
  while(q--){
    ll ans = 0;
    int l,r;
    scanf("%d%d",&l,&r);
    --l; --r;
    int u = l/sqrtn, v = r/sqrtn;
    ++u; --v;
    int leftright = u*sqrtn-1;
    int rightleft = (v+1)*sqrtn;
    if(u<=v){
      // [u,v]????????±??????????????£??¨????????§??????
      ans += s[u][v];
      // ?????´??¨[u,v]?????±???
      FOR(i,l,leftright+1){
        ll val = p[i];
        ans += f[v].sum(val-1);
        ans -= f[u-1].sum(val-1);
      }
      // ?????´??¨[u,v]?????±???
      FOR(i,rightleft,r+1){
        ll val = p[i];
        ans += f[v].revsum(val+1);
        ans -= f[u-1].revsum(val+1);
      }
    }
    // ??£???
    if(leftright<rightleft){
      // ?????¢
      FOR(i,l,leftright+1){
        ll val = p[i];
        ans += bit.revsum(val+1);
        bit.add(val,1);
      }
      FOR(i,rightleft,r+1){
        ll val = p[i];
        ans += bit.revsum(val+1);
        bit.add(val,1);
      }
      // ???????????????
      FOR(i,l,leftright+1){
        bit.add(p[i],-1);
      }
      FOR(i,rightleft,r+1){
        bit.add(p[i],-1);
      }
    }else{
      // ????????????
      int size = r-l+1;
      assert(size <= 2*sqrtn);
      FOR(i,l,r+1){
        ll val = p[i];
        ans += bit.revsum(val+1);
        bit.add(val,1);
      }
      // ???????????????
      FOR(i,l,r+1){
        bit.add(p[i],-1);
      }
    }
    printf("%d\n",ans);
  }
  return 0;
}
accuracy: 0.6176470588235294
time_ms: 30
memory_kb: 4296
final_rank: 15

code_snippet: #include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

inline int calcIndex(int i, int j) {
	return j * (j + 1) / 2 + (j - i);
}

int main() {
	const int BlockSize = 400;
	const int MaxN = 100000, MaxNumBlocks = (MaxN + BlockSize - 1) / BlockSize;
	static int counts[MaxNumBlocks + 1][MaxN + 1];
	static short counts2[BlockSize + 1][BlockSize + 1];

	int N;
	while(~scanf("%d", &N)) {
		int X = N;
		vector<int> p(N);
		for(int i = 0; i < N; ++ i) {
			scanf("%d", &p[i]), -- p[i];
		}
		int NumBlocks = (N + BlockSize - 1) / BlockSize;
		memset(counts, 0, sizeof counts);
		for(int bi = 0; bi < NumBlocks; ++ bi) {
			int L = bi * BlockSize, R = min((bi + 1) * BlockSize, N);
			for(int i = L; i < R; ++ i)
				++ counts[bi + 1][p[i] + 1];
			for(int x = 1; x <= X; ++ x)
				counts[bi + 1][x] += counts[bi][x] + counts[bi + 1][x - 1] - counts[bi][x - 1];
		}
		vector<vector<pair<int, int> > > sortedBlocks(NumBlocks);
		vector<vector<int> > inner(NumBlocks);
		for(int bi = 0; bi < NumBlocks; ++ bi) {
			int L = bi * BlockSize, R = min((bi + 1) * BlockSize, N);
			int M = R - L, Y = M;

			vector<pair<int, int> > &sorted = sortedBlocks[bi];
			sorted.resize(M);
			for(int i = L; i < R; ++ i)
				sorted[i - L] = make_pair(p[i], i);
			sort(sorted.begin(), sorted.end());
			
			vector<int> rank(M);
			for(int i = 0; i < M; ++ i)
				rank[sorted[i].second - L] = i;

			memset(counts2, 0, sizeof counts2);

			for(int i = 0; i < M; ++ i)
				++ counts2[i + 1][rank[i] + 1];
			for(int i = 0; i < M; ++ i) for(int y = 1; y <= Y; ++ y)
				counts2[i + 1][y] += counts2[i][y] + counts2[i + 1][y - 1] - counts2[i][y - 1];

			vector<int> &v = inner[bi];
			v.resize((R - L) * (R - L + 1) / 2);
			int k = 0;
			for(int j = 0; j < M; ++ j) {
				int sum = 0;
				for(int i = j; i >= 0; -- i) {
					sum += counts2[j + 1][rank[i]] - counts2[i + 1][rank[i]];
					v[k ++] = sum;
				}
			}
		}
		vector<vector<long long> > outer(NumBlocks + 1, vector<long long>(N));
		for(int bi = 0; bi <= NumBlocks; ++ bi) {
			vector<long long> &v = outer[bi];
			long long sum;
			sum = 0;
			for(int bj = bi; bj < NumBlocks; ++ bj) {
				int L = bj * BlockSize, R = min((bj + 1) * BlockSize, N);
				int num = (bj - bi) * BlockSize;
				for(int j = L; j < R; ++ j) {
					sum += num - (counts[bj][p[j] + 1] - counts[bi][p[j] + 1]);
					v[j] = sum;
				}
				sum += inner[bj][calcIndex(0, R - L - 1)];
			}
			sum = 0;
			for(int bj = bi - 1; bj >= 0; -- bj) {
				int L = bj * BlockSize, R = min((bj + 1) * BlockSize, N);
				for(int j = R - 1; j >= L; -- j) {
					sum += counts[bi][p[j]] - counts[bj + 1][p[j]];
					v[j] = sum;
				}
				sum += inner[bj][calcIndex(0, R - L - 1)];
			}
		}
		int Q;
		scanf("%d", &Q);
		for(int ii = 0; ii < Q; ++ ii) {
			int l; int r;
			scanf("%d%d", &l, &r), -- l;
			int bl = (l + BlockSize - 1) / BlockSize, br = r / BlockSize;
			long long ans = 0;
			if(l / BlockSize == (r - 1) / BlockSize) {
				ans = inner[l / BlockSize][calcIndex(l % BlockSize, (r - 1) % BlockSize)];
			} else {
				int L = bl * BlockSize, R = br * BlockSize;
				ans += outer[bl][r - 1];
				ans += inner[(r - 1) / BlockSize][calcIndex(0, (r - 1) % BlockSize)];
				if(l < R) {
					ans += outer[br][l];
					ans += inner[l / BlockSize][calcIndex(l % BlockSize, min(BlockSize, N - l / BlockSize * BlockSize) - 1)];
				}
				if(bl < br) {
					ans -= outer[bl][R - 1];
					ans -= inner[(R - 1) / BlockSize][calcIndex(0, BlockSize - 1)];
				}
				if(l < L && R < r) {
					const vector<pair<int, int> > &v = sortedBlocks[bl - 1], &w = sortedBlocks[br];
					int nv = (int)v.size(), nw = (int)w.size();
					for(int i = 0, j = 0, cnt = 0; i < nv; ++ i) {
						for(; j < nw && w[j].first < v[i].first; ++ j)
							cnt += w[j].second < r;
						if(l <= v[i].second)
							ans += cnt;
					}
				}
			}
			printf("%lld\n", ans);
			//fflush(stdout);
		}
	}
	return 0;
}
accuracy: 1
time_ms: 1350
memory_kb: 377236
final_rank: 9

code_snippet: #include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

inline int calcIndex(int i, int j) {
	return j * (j + 1) / 2 + (j - i);
}

int main() {
	const int BlockSize = 250;
	const int MaxN = 100000, MaxNumBlocks = (MaxN + BlockSize - 1) / BlockSize;
	static int counts[MaxNumBlocks + 1][MaxN + 1];
	static short counts2[BlockSize + 1][BlockSize + 1];

	int N;
	while(~scanf("%d", &N)) {
		int X = N;
		vector<int> p(N);
		for(int i = 0; i < N; ++ i) {
			scanf("%d", &p[i]), -- p[i];
		}
		int NumBlocks = (N + BlockSize - 1) / BlockSize;
		memset(counts, 0, sizeof counts);
		for(int bi = 0; bi < NumBlocks; ++ bi) {
			int L = bi * BlockSize, R = min((bi + 1) * BlockSize, N);
			for(int i = L; i < R; ++ i)
				++ counts[bi + 1][p[i] + 1];
			for(int x = 1; x <= X; ++ x)
				counts[bi + 1][x] += counts[bi][x] + counts[bi + 1][x - 1] - counts[bi][x - 1];
		}
		vector<vector<pair<int, int> > > sortedBlocks(NumBlocks);
		vector<vector<int> > inner(NumBlocks);
		for(int bi = 0; bi < NumBlocks; ++ bi) {
			int L = bi * BlockSize, R = min((bi + 1) * BlockSize, N);
			int M = R - L, Y = M;

			vector<pair<int, int> > &sorted = sortedBlocks[bi];
			sorted.resize(M);
			for(int i = L; i < R; ++ i)
				sorted[i - L] = make_pair(p[i], i);
			sort(sorted.begin(), sorted.end());
			
			vector<int> rank(M);
			for(int i = 0; i < M; ++ i)
				rank[sorted[i].second - L] = i;

			memset(counts2, 0, sizeof counts2);

			for(int i = 0; i < M; ++ i)
				++ counts2[i + 1][rank[i] + 1];
			for(int i = 0; i < M; ++ i) for(int y = 1; y <= Y; ++ y)
				counts2[i + 1][y] += counts2[i][y] + counts2[i + 1][y - 1] - counts2[i][y - 1];

			vector<int> &v = inner[bi];
			v.resize((R - L) * (R - L + 1) / 2);
			int k = 0;
			for(int j = 0; j < M; ++ j) {
				int sum = 0;
				for(int i = j; i >= 0; -- i) {
					sum += counts2[j + 1][rank[i]] - counts2[i + 1][rank[i]];
					v[k ++] = sum;
				}
			}
		}
		vector<vector<long long> > outer(NumBlocks + 1, vector<long long>(N));
		for(int bi = 0; bi <= NumBlocks; ++ bi) {
			vector<long long> &v = outer[bi];
			long long sum;
			sum = 0;
			for(int bj = bi; bj < NumBlocks; ++ bj) {
				int L = bj * BlockSize, R = min((bj + 1) * BlockSize, N);
				int num = (bj - bi) * BlockSize;
				for(int j = L; j < R; ++ j) {
					sum += num - (counts[bj][p[j] + 1] - counts[bi][p[j] + 1]);
					v[j] = sum;
				}
				sum += inner[bj][calcIndex(0, R - L - 1)];
			}
			sum = 0;
			for(int bj = bi - 1; bj >= 0; -- bj) {
				int L = bj * BlockSize, R = min((bj + 1) * BlockSize, N);
				for(int j = R - 1; j >= L; -- j) {
					sum += counts[bi][p[j]] - counts[bj + 1][p[j]];
					v[j] = sum;
				}
				sum += inner[bj][calcIndex(0, R - L - 1)];
			}
		}
		int Q;
		scanf("%d", &Q);
		for(int ii = 0; ii < Q; ++ ii) {
			int l; int r;
			scanf("%d%d", &l, &r), -- l;
			int bl = (l + BlockSize - 1) / BlockSize, br = r / BlockSize;
			long long ans = 0;
			if(l / BlockSize == (r - 1) / BlockSize) {
				ans = inner[l / BlockSize][calcIndex(l % BlockSize, (r - 1) % BlockSize)];
			} else {
				int L = bl * BlockSize, R = br * BlockSize;
				ans += outer[bl][r - 1];
				ans += inner[(r - 1) / BlockSize][calcIndex(0, (r - 1) % BlockSize)];
				if(l < R) {
					ans += outer[br][l];
					ans += inner[l / BlockSize][calcIndex(l % BlockSize, min(BlockSize, N - l / BlockSize * BlockSize) - 1)];
				}
				if(bl < br) {
					ans -= outer[bl][R - 1];
					ans -= inner[(R - 1) / BlockSize][calcIndex(0, BlockSize - 1)];
				}
				if(l < L && R < r) {
					const vector<pair<int, int> > &v = sortedBlocks[bl - 1], &w = sortedBlocks[br];
					int nv = (int)v.size(), nw = (int)w.size();
					for(int i = 0, j = 0, cnt = 0; i < nv; ++ i) {
						for(; j < nw && w[j].first < v[i].first; ++ j)
							cnt += w[j].second < r;
						if(l <= v[i].second)
							ans += cnt;
					}
				}
			}
			printf("%lld\n", ans);
			//fflush(stdout);
		}
	}
	return 0;
}
accuracy: 1
time_ms: 1270
memory_kb: 523108
final_rank: 12

code_snippet: #include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

inline int calcIndex(int i, int j) {
	return j * (j + 1) / 2 + (j - i);
}

int main() {
	const int BlockSize = 300;
	const int MaxN = 100000, MaxNumBlocks = (MaxN + BlockSize - 1) / BlockSize;
	static int counts[MaxNumBlocks + 1][MaxN + 1];
	static short counts2[BlockSize + 1][BlockSize + 1];

	int N;
	while(~scanf("%d", &N)) {
		int X = N;
		vector<int> p(N);
		for(int i = 0; i < N; ++ i) {
			scanf("%d", &p[i]), -- p[i];
		}
		int NumBlocks = (N + BlockSize - 1) / BlockSize;
		memset(counts, 0, sizeof counts);
		for(int bi = 0; bi < NumBlocks; ++ bi) {
			int L = bi * BlockSize, R = min((bi + 1) * BlockSize, N);
			for(int i = L; i < R; ++ i)
				++ counts[bi + 1][p[i] + 1];
			for(int x = 1; x <= X; ++ x)
				counts[bi + 1][x] += counts[bi][x] + counts[bi + 1][x - 1] - counts[bi][x - 1];
		}
		vector<vector<pair<int, int> > > sortedBlocks(NumBlocks);
		vector<vector<int> > inner(NumBlocks);
		for(int bi = 0; bi < NumBlocks; ++ bi) {
			int L = bi * BlockSize, R = min((bi + 1) * BlockSize, N);
			int M = R - L, Y = M;

			vector<pair<int, int> > &sorted = sortedBlocks[bi];
			sorted.resize(M);
			for(int i = L; i < R; ++ i)
				sorted[i - L] = make_pair(p[i], i);
			sort(sorted.begin(), sorted.end());
			
			vector<int> rank(M);
			for(int i = 0; i < M; ++ i)
				rank[sorted[i].second - L] = i;

			memset(counts2, 0, sizeof counts2);

			for(int i = 0; i < M; ++ i)
				++ counts2[i + 1][rank[i] + 1];
			for(int i = 0; i < M; ++ i) for(int y = 1; y <= Y; ++ y)
				counts2[i + 1][y] += counts2[i][y] + counts2[i + 1][y - 1] - counts2[i][y - 1];

			vector<int> &v = inner[bi];
			v.resize((R - L) * (R - L + 1) / 2);
			int k = 0;
			for(int j = 0; j < M; ++ j) {
				int sum = 0;
				for(int i = j; i >= 0; -- i) {
					sum += counts2[j + 1][rank[i]] - counts2[i + 1][rank[i]];
					v[k ++] = sum;
				}
			}
		}
		vector<vector<long long> > outer(NumBlocks + 1, vector<long long>(N));
		for(int bi = 0; bi <= NumBlocks; ++ bi) {
			vector<long long> &v = outer[bi];
			long long sum;
			sum = 0;
			for(int bj = bi; bj < NumBlocks; ++ bj) {
				int L = bj * BlockSize, R = min((bj + 1) * BlockSize, N);
				int num = (bj - bi) * BlockSize;
				for(int j = L; j < R; ++ j) {
					sum += num - (counts[bj][p[j] + 1] - counts[bi][p[j] + 1]);
					v[j] = sum;
				}
				sum += inner[bj][calcIndex(0, R - L - 1)];
			}
			sum = 0;
			for(int bj = bi - 1; bj >= 0; -- bj) {
				int L = bj * BlockSize, R = min((bj + 1) * BlockSize, N);
				for(int j = R - 1; j >= L; -- j) {
					sum += counts[bi][p[j]] - counts[bj + 1][p[j]];
					v[j] = sum;
				}
				sum += inner[bj][calcIndex(0, R - L - 1)];
			}
		}
		int Q;
		scanf("%d", &Q);
		for(int ii = 0; ii < Q; ++ ii) {
			int l; int r;
			scanf("%d%d", &l, &r), -- l;
			int bl = (l + BlockSize - 1) / BlockSize, br = r / BlockSize;
			long long ans = 0;
			if(l / BlockSize == (r - 1) / BlockSize) {
				ans = inner[l / BlockSize][calcIndex(l % BlockSize, (r - 1) % BlockSize)];
			} else {
				int L = bl * BlockSize, R = br * BlockSize;
				ans += outer[bl][r - 1];
				ans += inner[(r - 1) / BlockSize][calcIndex(0, (r - 1) % BlockSize)];
				if(l < R) {
					ans += outer[br][l];
					ans += inner[l / BlockSize][calcIndex(l % BlockSize, min(BlockSize, N - l / BlockSize * BlockSize) - 1)];
				}
				if(bl < br) {
					ans -= outer[bl][R - 1];
					ans -= inner[(R - 1) / BlockSize][calcIndex(0, BlockSize - 1)];
				}
				if(l < L && R < r) {
					const vector<pair<int, int> > &v = sortedBlocks[bl - 1], &w = sortedBlocks[br];
					int nv = (int)v.size(), nw = (int)w.size();
					for(int i = 0, j = 0, cnt = 0; i < nv; ++ i) {
						for(; j < nw && w[j].first < v[i].first; ++ j)
							cnt += w[j].second < r;
						if(l <= v[i].second)
							ans += cnt;
					}
				}
			}
			printf("%lld\n", ans);
			//fflush(stdout);
		}
	}
	return 0;
}
accuracy: 1
time_ms: 1260
memory_kb: 456736
final_rank: 10

code_snippet: #include <cstdio>
#include <algorithm>
#include <vector>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define pb push_back
#define sz(x) (int)(x).size()
using namespace std;
typedef long long int ll;
typedef vector<int> vi;

const int D = 300, E = 351, MX = 100005;
// Binary Indexed Tree
struct bit {
  vector<int> d; int n, hi;
  vi hist;
  bit() {}
  bit(int mx): n(mx), d(mx), hist(MX), hi(0) {}
  void add(int i, int x=1) {
    for (++i;i<n;i+=i&-i) {
      d[i] += x;
    }
  }
  void add2(int i, int x=1) {
    for (++i;i<n;i+=i&-i) {
      hist[hi++] = i;
      d[i] += x;
    }
  }
  int sum(int i) {
    int x = 0;
    for (++i;i;i-=i&-i) x += d[i];
    return x;
  }
  void rev() {
    d = vi(n);
  }
  void rev2() {
    while (hi--) d[hist[hi]] = 0;
    hi = 0;
  }
};
//
int n, a[MX];
vector<ll> dl[E], dr[E];
int main() {
  // preprocess
  scanf("%d",&n);
  rep(i,n) scanf("%d",&a[i]), a[i] = n-a[i];
  bit t(n+2);
  for (int i = 0; i <= n; i += D) {
    int di = i/D;
    ll sum = 0;
    for (int j = i; j < n; ++j) {
      sum += t.sum(a[j]);
      dl[di].pb(sum);
      t.add(a[j]);
    }
    t.rev();
    sum = 0;
    for (int j = i-1; j >= 0; --j) {
      sum += t.sum(n-a[j]);
      dr[di].pb(sum);
      t.add(n-a[j]);
    }
    t.rev();
  }
  // online query
  int q;
  scanf("%d",&q);
  rep(qi,q) {
    int l, r;
    scanf("%d%d",&l,&r);
    --l;
    ll ans = 0;
    if (r-l <= D) {
      for (int i = l; i < r; ++i) {
        ans += t.sum(a[i]);
        t.add2(a[i]);
      }
      t.rev2();
    } else {
      int li = l/D+1, ri = r/D;
      ans += dl[li][r-1-li*D];
      ans += dr[ri][ri*D-1-l];
      ans -= dl[li][ri*D-1-li*D];
      vi p;
      for (int i = li*D-1; i >= l; --i) p.pb(a[i]<<1);
      for (int i = ri*D; i < r; ++i) p.pb(a[i]<<1|1);
      sort(p.begin(), p.end());
      int s = 0;
      rep(i,sz(p)) {
        if (p[i]&1) ans += s;
        else s++;
      }
    }
    printf("%lld\n",ans);
  }
  return 0;
}
accuracy: 0.3235294117647059
time_ms: 40
memory_kb: 3412
final_rank: 18

code_snippet: #include <cstdio>
#include <algorithm>
#include <vector>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define pb push_back
#define sz(x) (int)(x).size()
using namespace std;
typedef long long int ll;
typedef vector<int> vi;

const int D = 300, E = 351, MX = 100005;
// Binary Indexed Tree
struct bit {
  vector<int> d; int n, hi;
  vi hist;
  bit() {}
  bit(int mx): n(mx), d(mx), hist(MX), hi(0) {}
  void add(int i, int x=1) {
    for (++i;i<n;i+=i&-i) {
      d[i] += x;
    }
  }
  void add2(int i, int x=1) {
    for (++i;i<n;i+=i&-i) {
      hist[hi++] = i;
      d[i] += x;
    }
  }
  int sum(int i) {
    int x = 0;
    for (++i;i;i-=i&-i) x += d[i];
    return x;
  }
  void rev() {
    d = vi(n);
  }
  void rev2() {
    while (hi--) d[hist[hi]] = 0;
    hi = 0;
  }
};
//
int n, a[MX];
vector<ll> dl[E], dr[E];
int main() {
  // preprocess
  scanf("%d",&n);
  rep(i,n) scanf("%d",&a[i]), a[i] = n-a[i];
  bit t(n+2);
  for (int i = 0; i <= n; i += D) {
    int di = i/D;
    ll sum = 0;
    for (int j = i; j < n; ++j) {
      sum += t.sum(a[j]);
      dl[di].pb(sum);
      t.add(a[j]);
    }
    t.rev();
    sum = 0;
    for (int j = i-1; j >= 0; --j) {
      sum += t.sum(n-a[j]);
      dr[di].pb(sum);
      t.add(n-a[j]);
    }
    t.rev();
  }
  // online query
  int q;
  scanf("%d",&q);
  rep(qi,q) {
    int l, r;
    scanf("%d%d",&l,&r);
    --l;
    ll ans = 0;
    if (r-l <= D) {
      for (int i = l; i < r; ++i) {
        ans += t.sum(a[i]);
        t.add2(a[i]);
      }
      t.rev2();
    } else {
      int li = l/D+1, ri = r/D;
      ans += dl[li][r-1-li*D];
      ans += dr[ri][ri*D-l];
      ans -= dl[li][ri*D-1-li*D];
      vi p;
      for (int i = li*D-1; i >= l; --i) p.pb(a[i]<<1);
      for (int i = ri*D; i < r; ++i) p.pb(a[i]<<1|1);
      sort(p.begin(), p.end());
      int s = 0;
      rep(i,sz(p)) {
        if (p[i]&1) ans += s;
        else s++;
      }
    }
    printf("%lld\n",ans);
  }
  return 0;
}
accuracy: 0.3235294117647059
time_ms: 40
memory_kb: 3412
final_rank: 18

code_snippet: #include <cstdio>
#include <algorithm>
#include <vector>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define pb push_back
#define sz(x) (int)(x).size()
using namespace std;
typedef long long int ll;
typedef vector<int> vi;

const int D = 300, E = 351, MX = 100005;
// Binary Indexed Tree
struct bit {
  vector<int> d; int n, hi;
  vi hist;
  bit() {}
  bit(int mx): n(mx), d(mx), hist(MX), hi(0) {}
  void add(int i, int x=1) {
    for (++i;i<n;i+=i&-i) {
      d[i] += x;
    }
  }
  void add2(int i, int x=1) {
    for (++i;i<n;i+=i&-i) {
      hist[hi++] = i;
      d[i] += x;
    }
  }
  int sum(int i) {
    int x = 0;
    for (++i;i;i-=i&-i) x += d[i];
    return x;
  }
  void rev() {
    d = vi(n);
  }
  void rev2() {
    while (hi--) d[hist[hi]] = 0;
    hi = 0;
  }
};
//
int n, a[MX];
ll dl[E][MX], dr[E][MX];
int main() {
  // preprocess
  scanf("%d",&n);
  rep(i,n) scanf("%d",&a[i]), a[i] = n-a[i];
  bit t(n+2);
  for (int i = 0; i <= n; i += D) {
    int di = i/D;
    ll sum = 0;
    for (int j = i; j < n; ++j) {
      sum += t.sum(a[j]);
      dl[di][j] = sum;
      t.add(a[j]);
    }
    t.rev();
    sum = 0;
    for (int j = i-1; j >= 0; --j) {
      sum += t.sum(n-a[j]);
      dr[di][j] = sum;
      t.add(n-a[j]);
    }
    t.rev();
  }
  // online query
  int q;
  scanf("%d",&q);
  rep(qi,q) {
    int l, r;
    scanf("%d%d",&l,&r);
    --l;
    ll ans = 0;
    if (r-l <= D) {
      for (int i = l; i < r; ++i) {
        ans += t.sum(a[i]);
        t.add2(a[i]);
      }
      t.rev2();
    } else {
      int li = l/D+1, ri = r/D;
      ans += dl[li][r-1];
      ans += dr[ri][l];
      ans -= dl[li][ri*D-1];
      vi p;
      for (int i = li*D-1; i >= l; --i) p.pb(a[i]<<1);
      for (int i = ri*D; i < r; ++i) p.pb(a[i]<<1|1);
      sort(p.begin(), p.end());
      int s = 0;
      rep(i,sz(p)) {
        if (p[i]&1) ans += s;
        else s++;
      }
    }
    printf("%lld\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 2720
memory_kb: 267636
final_rank: 13

code_snippet: #include <vector>
#include <utility>
#include <algorithm>
#include <cstdio>
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 = 500;
		int 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);
				}
			}
		}
		vector<vector<pair<int, int> > > sortedBlocks(NumBlocks);
		vector<int> rankInBlock(N, -1);
		for(int bi = 0; bi < NumBlocks; ++ bi) {
			int L = bi * BlockSize, R = min((bi + 1) * BlockSize, N);
			vector<pair<int, int> > &v = sortedBlocks[bi];
			v.resize(R - L);
			for(int i = L; i < R; ++ i)
				v[i - L] = make_pair(p[i], i);
			sort(v.begin(), v.end());
			for(int i = 0; i < R - L; ++ i)
				rankInBlock[v[i].second] = i;
		}
		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) {
				ft.init(BlockSize);
				for(int i = r; i >= l; -- i) {
					ans += ft.sum(rankInBlock[i]);
					ft.add(rankInBlock[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];
				if(l < L && R <= r) {
					const vector<pair<int, int> > &v = sortedBlocks[bl - 1], &w = sortedBlocks[br];
					int nv = (int)v.size(), nw = (int)w.size();
					for(int i = 0, j = 0, cnt = 0; i < nv; ++ i) {
						for(; j < nw && w[j].first < v[i].first; ++ j)
							cnt += w[j].second <= r;
						if(l <= v[i].second)
							ans += cnt;
					}
				}
			}
			printf("%lld\n", ans);
		}
	}
	return 0;
}
accuracy: 1
time_ms: 1670
memory_kb: 160564
final_rank: 7

code_snippet: #include <vector>
#include <utility>
#include <algorithm>
#include <cstdio>
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 = 500;
		int 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);
				}
			}
		}
		vector<vector<pair<int, int> > > sortedBlocks(NumBlocks);
		vector<int> rankInBlock(N, -1);
		for(int bi = 0; bi < NumBlocks; ++ bi) {
			int L = bi * BlockSize, R = min((bi + 1) * BlockSize, N);
			vector<pair<int, int> > &v = sortedBlocks[bi];
			v.resize(R - L);
			for(int i = L; i < R; ++ i)
				v[i - L] = make_pair(p[i], i);
			sort(v.begin(), v.end());
			for(int i = 0; i < R - L; ++ i)
				rankInBlock[v[i].second] = i;
		}
		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) {
				ft.init(BlockSize);
				for(int i = r; i >= l; -- i) {
					ans += ft.sum(rankInBlock[i]);
					ft.add(rankInBlock[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];
				if(l < L && R <= r) {
					const vector<pair<int, int> > &v = sortedBlocks[bl - 1], &w = sortedBlocks[br];
					int nv = (int)v.size(), nw = (int)w.size();
					for(int i = 0, j = 0, cnt = 0; i < nv; ++ i) {
						for(; j < nw && w[j].first < v[i].first; ++ j)
							cnt += w[j].second <= r;
						if(l <= v[i].second)
							ans += cnt;
					}
				}
			}
			printf("%lld\n", ans); fflush(stdout);
		}
	}
	return 0;
}
accuracy: 1
time_ms: 2060
memory_kb: 160564
final_rank: 8

code_snippet: #include <vector>
#include <cstdio>
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);
		}
	}
	return 0;
}
accuracy: 1
time_ms: 2600
memory_kb: 316488
final_rank: 14