【2017 ACM/ICPC 乌鲁木齐赛区网络赛环境测试赛 E】蒜头君的排序

【链接】h在这里写链接


【题意】


在这里写题意

【题解】


莫队算法+树状数组。
区间增加1或减少1.
对逆序对的影响是固定的。
(用冒泡排序变成升序的交换次数,就是逆序对的个数)

【错的次数】


0

【反思】


在这了写反思

【代码】

#include <bits/stdc++.h>
using namespace std;

const int N = 3e4;

int n,m, a[N + 10], l, r;
long long ans[N + 10],now = 0;

struct BI {
    int a[N + 10];

    int lowbit(int x) {
        return x&(-x);
    }

    void add(int x,int y) {
        while (x <= N) {
            a[x] += y;
            x += lowbit(x);
        }
    }

    int sum(int x) {
        int now = 0;
        while (x > 0) {
            now += a[x];
            x -= lowbit(x);
        }
        return now;
    }

    int get_sum(int l, int r) {
        return sum(r) - sum(l - 1);
    }
}BIT;

struct abc {
    int l, r, id;
}Q[N+10];

bool cmp(abc a, abc b) {
    if (a.l / 100 == b.l / 100) {
        return a.r < b.r;
    }
    else
        return a.l < b.l;
}

int main() {
    //freopen("F:\rush.txt", "r", stdin);
    ios::sync_with_stdio(0);
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    cin >> m;
    for (int i = 1; i <= m; i++) {
        cin >> Q[i].l >> Q[i].r;
        Q[i].id = i;
    }
    sort(Q + 1, Q + 1 + m, cmp);
    l = 1, r = 1, BIT.add(a[1], 1), now = 0;
    for (int i = 1; i <= m; i++) {
        while (r < Q[i].r) {
            r++;
            now += BIT.get_sum(a[r] + 1, n);
            BIT.add(a[r], 1);
        }
        while (l > Q[i].l) {
            l--;
            now += BIT.get_sum(1, a[l] - 1);
            BIT.add(a[l], 1);
        }
        while (r > Q[i].r) {
            now -= BIT.get_sum(a[r] + 1, n);
            BIT.add(a[r], -1);
            r--;
        }
        while (l < Q[i].l) {
            now -= BIT.get_sum(1, a[l] - 1);
            BIT.add(a[l], -1);
            l++;
        }
        ans[Q[i].id] = now;
    }
    for (int i = 1; i <= m; i++) 
        cout << ans[i] << endl;
    return 0;
}


原文地址:https://www.cnblogs.com/AWCXV/p/7626034.html