bzoj 3295 CDQ求动态逆序对

bzoj 3295  CDQ求动态逆序对

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define PLI pair<LL, int>
#define PLL pair<LL, LL>
#define y1 skldjfskldjg
#define y2 skldfjsklejg

using namespace std;

const int N = 1e5 + 7;
const int M = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 +7;
const double PI = acos(-1);
const double eps = 1e-7;

int n, m, pos[N], R[N], L[N];
LL ans[N];

struct BIT {
    int a[N];
    void modify(int x, int v) {
        for(int i = x; i <= n; i += i & -i)
            a[i] += v;
    }
    int sum(int x) {
        int ans = 0;
        for(int i = x; i; i -= i & -i)
            ans += a[i];
        return ans;
    }

} bit;

struct QUS {
    int t, x, val;
} qus[N], tmp[N];

void cdq(int l, int r) {
    if(l == r) return;
    int mid = l + r >> 1;
    cdq(l, mid); cdq(mid + 1, r);

    int j = l;
    for(int i = mid + 1; i <= r; i++) {
        while(j <= mid && qus[j].x < qus[i].x) bit.modify(qus[j++].val, 1);
        L[qus[i].t] += bit.sum(n) - bit.sum(qus[i].val);
    }
    for(int i = j - 1; i >= l; i--) bit.modify(qus[i].val, -1);

    j = mid;
    for(int i = r; i >= mid + 1; i--) {
        while(j >= l && qus[j].x > qus[i].x) bit.modify(qus[j--].val, 1);
        R[qus[i].t] += bit.sum(qus[i].val - 1);
    }
    for(int i = j + 1; i <= mid; i++) bit.modify(qus[i].val, - 1);

    int tot = l, p = l, q = mid + 1;
    while(p <= mid && q <= r) {
        if(qus[p].x < qus[q].x) tmp[tot++] = qus[p++];
        else tmp[tot++] = qus[q++];
    }
    while(p <= mid) tmp[tot++] = qus[p++];
    while(q <= r) tmp[tot++] = qus[q++];
    for(int i = l; i <= r; i++) qus[i] = tmp[i];
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        int val; scanf("%d", &val);
        pos[val] = i;
    }

    int idx = n;
    for(int i = 1; i <= m; i++) {
        int val; scanf("%d", &val);
        qus[idx].val = val;
        qus[idx].t = idx;
        qus[idx--].x = pos[val];
        pos[val] = -1;
    }

    for(int i = 1; i<= n; i++) {
        if(pos[i] != -1) {
            qus[idx].val = i;
            qus[idx].t = idx;
            qus[idx--].x = pos[i];
            pos[i] = -1;
        }
    }

    cdq(1, n);
    for(int i = 1; i <= n; i++) ans[i] = ans[i - 1] + R[i] + L[i];
    for(int i = n; i > n - m; i--) printf("%lld
", ans[i]);
    return 0;
}
/*
*/