传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3289

多组询问求区间内的逆序对数,莫队算法直接搞就行了。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int maxn = 50010;
struct node {
    int l, r, lp, pos;
    bool operator < (node t) const {
        return lp < t.lp || (lp == t.lp && r < t.r);
    }
}ask[maxn];
int num[maxn], num2[maxn], w[maxn], a[maxn], key[maxn];
int n, q, cnt, ans;
void update(int x, int v) {
    while(x <= cnt) {
        num[x] += v;
        x += x & -x;
    }
    return;
}
int sum(int x) {
    int res = 0;
    while(x) {
        res += num[x];
        x -= x & -x;
    }
    return res;
}
void update2(int x, int v) {
    while(x <= cnt) {
        num2[x] += v;
        x += x & -x;
    }
    return;
}
int sum2(int x) {
    int res = 0;
    while(x) {
        res += num2[x];
        x -= x & -x;
    }
    return res;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) {
        scanf("%d", &a[i]);
        w[i] = a[i];
    }
    sort(w + 1, w + n + 1);
    cnt = unique(w + 1, w + n + 1) - w - 1;
    for(int i = 1; i <= n; i ++) {
        a[i] = lower_bound(w + 1, w + cnt + 1, a[i]) - w;
    }
    scanf("%d", &q);
    int len = (int)(sqrt(n) + 0.5);
    for(int i = 1; i <= q; i ++) {
        scanf("%d%d", &ask[i].l, &ask[i].r);
        ask[i].lp = (ask[i].l - 1) / len + 1;
        ask[i].pos = i;
    }
    sort(ask + 1, ask + q + 1);
    int pl = 1, pr = 0;
    for(int i = 1; i <= q; i ++) {
        if(pr < ask[i].r) {
            for(pr ++; pr <= ask[i].r; pr ++) {
                ans += sum(cnt + 1 - a[pr]);
                update(cnt + 1 - a[pr] + 1, 1);
                update2(a[pr] + 1, 1);
            }
            pr --;
        } else if(pr > ask[i].r) {
            for(; pr > ask[i].r; pr --) {
                ans -= sum(cnt + 1 - a[pr]);
                update(cnt + 1 - a[pr] + 1, -1);
                update2(a[pr] + 1, -1);
            }
        }
        if(pl < ask[i].l) {
            for(; pl < ask[i].l; pl ++) {
                ans -= sum2(a[pl]);
                update(cnt + 1 - a[pl] + 1, -1);
                update2(a[pl] + 1, -1);
            }
        } else if(pl > ask[i].l) {
            for(pl --; pl >= ask[i].l; pl --) {
                ans += sum2(a[pl]);
                update(cnt + 1 - a[pl] + 1, 1);
                update2(a[pl] + 1, 1);
            }
            pl ++;
        }
        key[ask[i].pos] = ans;
    }
    for(int i = 1; i <= q; i ++) printf("%d\n", key[i]);
    return 0;
}