• [国家集训队]排队


    分块套平衡树即可。

    当然里面的平衡树由于只需要支持插入删除和询问某一段值域的值的个数可以map树状数组。

    (请忽略本次的压行)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 50005, sqr = 300;
    int n, a[N], m, t;
    LL ans;
    map<int, int> cc;
    void upd(int v) {
        for (; v <= 1e9; v += (v & -v)) cc[v]++;
    }
    int qq(int v) {
        int ans1 = 0;
        for (; v; v -= (v & -v)) ans1 += cc[v];
        return ans1;
    }
    int Lb[sqr], Rb[sqr], pos[N], rt[sqr], ls[N], rs[N], sz[N], rd[N], vl[N], cnt = 0;
    int nd(int v) {
        vl[++cnt] = v;
        ls[cnt] = rs[cnt] = 0;
        sz[cnt] = 1;
        return cnt;
    }
    void pu(int p) { sz[p] = sz[ls[p]] + sz[rs[p]] + 1; }
    void split(int p, int& l, int& r, int v) {
        if (!p) {
            l = r = 0;
            return;
        }
        if (vl[p] <= v)
            l = p, split(rs[p], rs[l], r, v);
        else
            r = p, split(ls[p], l, ls[r], v);
        pu(p);
    }
    void merge(int& p, int l, int r) {
        if (!l || !r) {
            p = l + r;
            return;
        }
        if (rand() % sz[l] < rand() % sz[r])
            p = l, merge(rs[p], rs[l], r);
        else
            p = r, merge(ls[p], l, ls[r]);
        pu(p);
    }
    void ins(int& r, int v) {
        int a = 0, b = 0;
        split(r, a, b, v), merge(a, a, nd(v)), merge(r, a, b);
    }
    void del(int& r, int v) {
        int a = 0, b = 0, c = 0;
        split(r, a, b, v), split(a, a, c, v - 1), merge(c, ls[c], rs[c]), merge(a, a, c), merge(r, a, b);
    }
    int smlthan(int& r, int p) {
        int a = 0, b = 0;
        split(r, a, b, p - 1);
        int as = sz[a];
        merge(r, a, b);
        return as;
    }
    int bigthan(int& r, int p) {
        int a = 0, b = 0;
        split(r, a, b, p);
        int as = sz[b];
        merge(r, a, b);
        return as;
    }
    void work() {
        t = (int)sqrt(n);
        for (int i = 1; i <= t; i++) {
            Lb[i] = Rb[i - 1] + 1, Rb[i] = Lb[i] + t - 1;
            for (int j = Lb[i]; j <= Rb[i]; j++) pos[j] = i, ins(rt[i], a[j]);
        }
        if (t * t < n) {
            ++t;
            Lb[t] = Rb[t - 1] + 1;
            Rb[t] = n;
            for (int j = Lb[t]; j <= Rb[t]; j++) pos[j] = t, ins(rt[t], a[j]);
        }
    }
    void swp(int l, int r) {
        if (pos[l] == pos[r]) {
            int sum = 0;
            for (register int i = l + 1; i <= r - 1; i++) sum += (a[l] > a[i]) + (a[i] > a[r]);
            sum += (a[l] > a[r]);
            ans -= sum;
            swap(a[l], a[r]);
            for (register int i = l + 1; i <= r - 1; i++) ans += (a[l] > a[i]) + (a[i] > a[r]);
            ans += (a[l] > a[r]);
            return;
        }
        int sum = 0;
        for (register int i = l + 1; i <= Rb[pos[l]]; i++) sum += (a[l] > a[i]) + (a[i] > a[r]);
        for (register int i = Lb[pos[r]]; i <= r - 1; i++) sum += (a[l] > a[i]) + (a[i] > a[r]);
        for (register int b = pos[l] + 1; b <= pos[r] - 1; b++)
            sum += smlthan(rt[b], a[l]) + bigthan(rt[b], a[r]);
        sum += (a[l] > a[r]);
        del(rt[pos[l]], a[l]);
        del(rt[pos[r]], a[r]);
        swap(a[l], a[r]);
        ins(rt[pos[r]], a[r]);
        ins(rt[pos[l]], a[l]);
        ans -= sum;
        for (register int i = l + 1; i <= Rb[pos[l]]; i++) ans += (a[l] > a[i]) + (a[i] > a[r]);
        for (register int i = Lb[pos[r]]; i <= r - 1; i++) ans += (a[l] > a[i]) + (a[i] > a[r]);
        for (register int b = pos[l] + 1; b <= pos[r] - 1; b++)
            ans += smlthan(rt[b], a[l]) + bigthan(rt[b], a[r]);
        ans += (a[l] > a[r]);
    }
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        work();
        for (int i = n; i >= 1; i--) {
            ans += qq(a[i] - 1);
            upd(a[i]);
        }
        printf("%lld
    ", ans);
        scanf("%d", &m);
        while (m--) {
            int l, r;
            scanf("%d%d", &l, &r);
            if (l > r)
                swap(l, r);
            swp(l, r);
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    centos ftp搭建
    python_模块
    python_如何建立包
    python_类
    python_递归
    python_函数
    python_字典
    python_条件、循环语句
    python_中文乱码问题
    Viola–Jones object detection framework--Rapid Object Detection using a Boosted Cascade of Simple Features中文翻译 及 matlab实现(见文末链接)
  • 原文地址:https://www.cnblogs.com/LiM-817/p/11913383.html
Copyright © 2020-2023  润新知