zoukankan      html  css  js  c++  java
  • 动态逆序对

    CDQ分治
    把删除转变为逐个添加,于是就变成了三维偏序问题
    时间,位置,大小
    分两遍统计即可

    # include <stdio.h>
    # include <stdlib.h>
    # include <iostream>
    # include <algorithm>
    # include <string.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
        return x * z;
    }
    
    const int MAXN(100010);
    int n, a[MAXN], id[MAXN], vis[MAXN], m, del[MAXN];
    ll ans[MAXN], t[MAXN];
    struct Point{
        int a, b, c;
        ll ans;
        IL bool operator <(RG Point B) const{  return a < B.a;  }
    } p[MAXN], q[MAXN];
    
    IL void Add(RG int x, RG int d){  for(; x <= n; x += x & -x) t[x] += d;  }
    
    IL int Query(RG int x){  RG int cnt = 0; for(; x; x -= x & -x) cnt += t[x]; return cnt;  } 
    
    IL void CDQ(RG int l, RG int r){
        if(l == r) return;
        RG int mid = (l + r) >> 1, le = 0; CDQ(l, mid); CDQ(mid + 1, r);
        for(RG int i = l, j = mid + 1, len = l; i <= mid || j <= r; )
            if(j > r || (i <= mid && p[i].b < p[j].b)) q[len++] = p[i++];
            else q[len++] = p[j++];
        for(RG int i = l; i <= r; i++) p[i] = q[i];
        for(RG int i = l; i <= r; i++)
            if(p[i].a <= mid) Add(p[i].c, 1), le++;
            else p[i].ans += le - Query(p[i].c);
        for(RG int i = l; i <= r; i++)
            if(p[i].a <= mid) Add(p[i].c, -1);
        for(RG int i = r; i >= l; i--)
            if(p[i].a <= mid) Add(p[i].c, 1);
            else p[i].ans += Query(p[i].c);
        for(RG int i = r; i >= l; i--)
            if(p[i].a <= mid) Add(p[i].c, -1);
    }
    
    int main(RG int argc, RG char* argv[]){
        n = Read(); m = Read(); RG int cnt = 0;
        for(RG int i = 1; i <= n; i++) a[i] = Read(), id[a[i]] = i;
        for(RG int i = 1; i <= m; i++) del[i] = Read(), vis[id[del[i]]] = 1;
        for(RG int i = 1; i <= n; i++) if(!vis[i]) p[++cnt] = (Point){cnt, i, a[i]};
        for(RG int i = m; i; i--) p[++cnt] = (Point){cnt, id[del[i]], del[i]};
        CDQ(1, n);
        sort(p + 1, p + n + 1);
        for(RG int i = 1; i <= n; i++) ans[i] = ans[i - 1] + p[i].ans;
        for(RG int i = n; i > n - m; i--) printf("%lld
    ", ans[i]);
        return 0;
    }
    
  • 相关阅读:
    正则表达式
    git指令
    前端测试 Jest/(Mocha) Typescript/Javascript Vueunitstest
    mpvue使用wxcharts.js显示各类图表
    css margintop 失效
    reduce 黑科技
    vue cli 项目创建
    css实现垂直水平居中
    MySQL基础教程之存储过程
    4组Alpha冲刺2/6
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206376.html
Copyright © 2011-2022 走看看