• 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;
    }
    /*
    */
  • 相关阅读:
    hdu多校4
    hdu多校第三场
    牛客多校4
    bzoj 1477 扩展欧几里德
    bzoj 1485 卡特兰数 + 分解因子
    hdu多校 2
    牛客网暑期多校2
    bzoj 1040 基向内环树dp
    hdu 多校第一场
    SPOJ
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9437513.html
Copyright © 2020-2023  润新知