動態逆序對(CQOI)(CDQ分治 or 主席樹)

2021-09-26 22:53:07 字數 1058 閱讀 7037

先寫乙個cdq分治的寫法吧,主席樹。。。希望我以後會補。

題意:先給定乙個1

11~n

nn的全排列,然後有m

mm次刪除操作,求每次刪除操作之前逆序對的個數。

思路:題目說求刪除操作之前逆序對的個數,反過來不就是每次插入操作之後逆序對的個數嗎?然後如果能求出每次插入操作所增加的逆序對個數,再利用字首和不就可以得到答案了嗎?

對,就是這麼簡單,把題目反過來,然後cdq分治,cdq部分難度比較低。

cdq部分:第一維按時間維度(反過來的時間),第二維按照插入元素的位置排序(兩遍),第三維就是直接把元素的值插入樹狀陣列中,然後統計答案。

#include "bits/stdc++.h"

#define hhh printf("hhh\n")

#define see(x) (cerr<<(#x)<<'='<<(x)inline int read()

const int maxn = 1e5+10;

const int mod = 1e9+7;

const double eps = 1e-7;

struct pp[maxn];

int n, m, q;

int pos[maxn], vis[maxn], del[maxn];

int b[maxn];

ll num[maxn];

bool cmp1(const p &a, const p &b)

inline void update(int x, int d)

inline int query(int x)

void solve(int l, int r)

while(--j>=l) update(p[j].v,-1);

}int main() ;

solve(1,n);

for(int i=1; i<=m; ++i) num[i]+=num[i-1];

for(int i=m; i; --i) printf("%lld\n", num[i]);

}

動態逆序對 CDQ分治

對於序列a,它的逆序對數定義為滿足iaj的數對 i,j 的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。輸入格式 輸入第一行包含兩個整數n和m,即初始元素的個數和刪除的元素個數。以下n行每行包含乙個1到n之間的正整數,即初始排列。以下...

Luogu1393 動態逆序對(CDQ分治)

對於給定的一段正整數序列,我們定義它的逆序對的個數為序列中ai aj且i j的有序對 i,j 的個數。你需要計算出乙個序列的逆序對組數及其刪去其中的某個數的逆序對組數。輸入格式 第一行,兩個數n,m,表示序列中有n個數,要刪去m個數 第二行n個數,表示給定的序列。第三行m個數,第i個數di表示要刪去...

bzoj3295 動態逆序對(CDQ分治)

time limit 10 sec memory limit 128 mb submit 7178 solved 2548 submit status discuss 對於序列a,它的逆序對數定義為滿足iaj的數對 i,j 的個數。給1到n的乙個排列,按照某種順序依次刪 除m個元素,你的任務是在每次...