zoukankan      html  css  js  c++  java
  • [国家集训队]排队

    分块套平衡树即可。

    当然里面的平衡树由于只需要支持插入删除和询问某一段值域的值的个数可以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;
    }
    
  • 相关阅读:
    [敏捷软工团队博客]Beta阶段项目展示
    [敏捷软工团队博客]Beta阶段使用指南
    [敏捷软工团队博客]Beta阶段测试报告
    [敏捷软工团队博客]Beta阶段发布声明
    [Beta]the Agiles Scrum Meeting 12
    [Beta]the Agiles Scrum Meeting 11
    [Beta]the Agiles Scrum Meeting 10
    [Beta]the Agiles Scrum Meeting 9
    [Beta]the Agiles Scrum Meeting 8
    2020BUAA-个人博客-案例分析
  • 原文地址:https://www.cnblogs.com/LiM-817/p/11913383.html
Copyright © 2011-2022 走看看