Description

排排坐, 吃果果, 生果甜嗦嗦, 大家笑呵呵. 你一个, 我一个, 大的分给你, 小的留给我, 吃完果果唱支歌, 大家乐和和.

红星幼儿园的小朋友们排起了长长地队伍, 准备吃果果. 不过因为小朋友们的身高有所区别, 排成的队伍高低错乱, 极不美观. 设第 \(i\) 个小朋友的身高为 \(h_i\), 我们定义一个序列的杂乱程度为: 满足 \(h_i \gt h_j\)\((i, j)\) 数量. 幼儿园阿姨每次会选出两个小朋友, 交换他们的位置, 请你帮忙计算出每次交换后, 序列的杂乱程度. 为方便幼儿园阿姨统计, 在未进行任何交换操作时, 你也应该输出该序列的杂乱程度.

Input

第一行为一个正整数 \(n\), 表示小朋友的数量;

第二行包含 \(n\) 个由空格分隔的正整数 \(h_1, h_2, \ldots, h_n\), 依次表示初始队列中小朋友的身高;

第三行为一个正整数 \(m\), 表示交换操作的次数;

以下 \(m\) 行每行包含两个正整数 \(a_i, b_i\), 表示交换位置 \(a_i\) 与位置 \(b_i\) 的小朋友.

Output

输出文件共 \(m\) 行, 第 \(i\) 行一个正整数表示交换操作 \(i\) 结束后, 序列的杂乱程度.

Sample Input

3
130 150 140
2
2 3
1 3

Sample Output

1
0
3

Data Range

对于 100% 的数据,\(1 \leq m \leq 2000, 1 \leq n \leq 20000, 1 \leq h_i \leq 10^9, a_i \neq b_i, 1 \leq a_i, b_i \leq n\)

Explanation

看一眼发现不会做然后觉得题解明显就是暴力的说......

既然都是分块了还不是暴力那是什么......

注意有可能出现重复的, 所以有大于和小于两种判断方式, 且集合不一定互补.

然后把题号写成 2143 怒调了好久无限 RE......

这样就要把所有元素分成 \(\sqrt{n}\) 块, 在每一块内查询复杂度为 \(O(\log \sqrt{n})\), 在所有块中执行查询操作得到的复杂度为 \(O(\sqrt{n} \log \sqrt{n})\); 然而修改的复杂度较为奇怪, 为 \(O(\sqrt{n} \log \sqrt{n})\) 每次.

Source Code


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;
typedef long long lli;
const int maxn = 20010;

class BinaryIndexedTree { public:
    int n, dat[maxn];
    inline int lowbit(int x) {
        return x & (-x); }
    void change(int x, int val) {
        for (; x <= n; x += lowbit(x)) dat[x] += val;
        return ; }
    int query(int x) { int res = 0;
        for (; x > 0; x -= lowbit(x)) res += dat[x];
        return res; }
    void init(int n) { this->n = n; return ; }
} bit;

int n, m, block, cnt;
int l[maxn], r[maxn]; // Block boundaries
int belong[maxn]; // Item belongings
int disc[maxn], a[maxn], b[maxn]; // Descatterization and height

void rebuild(int x)
{
    for (int i = l[x]; i <= r[x]; i++)
        a[i] = b[i];
    sort(a + l[x], a + r[x] + 1);
    return ;
}

int find(bool type, int l, int r, int x)
{
    int res = type ? r + 1 : l - 1,
        t = type ? r : l;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if ((type && a[mid] > x) || (!type && a[mid] < x))
            res = mid, (type ? r : l) = mid + (type ? -1 : 1);
        else (type ? l : r) = mid + (type ? 1 : -1);
    }
    return type ? t - res + 1 : res - t + 1;
}

void solve(int x, int y, int& res)
{
    if (x == y) return ;
    // Swapping between the two causes differences
    if (b[x] < b[y]) res += 1;
    if (b[x] > b[y]) res -= 1;
    // Determining whether in the same block
    if (belong[x] == belong[y]) {
        for (int i = x + 1; i < y; i++) {
            if (b[i] > b[x]) res += 1;
            if (b[i] < b[x]) res -= 1;
            if (b[i] > b[y]) res -= 1;
            if (b[i] < b[y]) res += 1;
        }
    } else {
        int L = r[belong[x]], R = l[belong[y]];
        for (int i = x + 1; i <= L; i++) {
            if (b[i] > b[x]) res += 1;
            if (b[i] < b[x]) res -= 1;
            if (b[i] > b[y]) res -= 1;
            if (b[i] < b[y]) res += 1;
        }
        for (int i = R; i < y; i++) {
            if (b[i] > b[x]) res += 1;
            if (b[i] < b[x]) res -= 1;
            if (b[i] > b[y]) res -= 1;
            if (b[i] < b[y]) res += 1;
        }
        for (int i = belong[x] + 1; i < belong[y]; i++) {
            res -= find(false, l[i], r[i], b[x]);
            res += find(false, l[i], r[i], b[y]);
            res += find(true, l[i], r[i], b[x]);
            res -= find(true, l[i], r[i], b[y]);
        }
    }
    swap(b[x], b[y]);
    rebuild(belong[x]), rebuild(belong[y]);
    return ;
}

int main(int argc, char** argv)
{
    scanf("%d", &n);
    // Initializing block settings
    block = sqrt(n);
    cnt = n % block ? n / block + 1 : n / block;
    for (int i = 1; i <= cnt; i++)
        l[i] = (i-1) * block + 1,
        r[i] = i * block;
    r[cnt] = n; // Delimitation
    for (int i = 1; i <= n; i++)
        belong[i] = (i-1) / block + 1;
    // De-scatterizing datum
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]),
        disc[i] = a[i];
    sort(disc + 1, disc + n + 1);
    for (int i = 1; i <= n; i++)
        a[i] = b[i] = lower_bound(disc + 1, disc + n + 1, a[i]) - disc;
    // Getting initial status, stating how many are different
    int res = 0;
    bit.init(n);
    for (int i = n; i >= 1; i--)
        res += bit.query(b[i] - 1),
        bit.change(b[i], 1);
    for (int i = 1; i <= cnt; i++)
        rebuild(i);
    printf("%d\n", res);
    // Getting data for each position
    scanf("%d", &m);
    for (int i = 1, x, y; i <= m; i++) {
        scanf("%d%d", &x, &y);
        if (x > y) swap(x, y);
        solve(x, y, res);
        printf("%d\n", res);
    }
    return 0;
}