CQOI2011 動態逆序對 CDQ分治

2021-09-25 09:31:31 字數 2646 閱讀 7597

還是比較模板的題可是一開始沒想出來。。之前電科校賽就遇到這道原題,今天終於補上了。。

主要的思路還是計算出每個數對前面和後面的影響,然後刪除的時候用總的減去就好了。。

但是問題在於,對於刪除操作怎麼動態的維護前後關係:當刪除乙個數a[i]之後,要知道在1…i-1範圍內有多少比a[i]大,在i+1…n中有多少比a[x]小的。

當然樹套樹可以做,但是常數和空間都比較大。這個時候就可以用cdq分治了。。

我們可以把刪除操作當做按時間t插入,對於乙個數,它的貢獻就是

(t』 < t && pos』 < pos && val』 > val )+ (t』 < t && pos』 > pos && val』 < val)的數量。

這個t相當於乙個 查詢貢獻的優先等級 (對於乙個逆序對,它屬於兩個數中哪乙個貢獻的?),結合題目,第乙個插入的優先等級肯定要高,然後依次降低。對於沒有刪除的數,隨便乙個遞減的組合都行。

每個數的貢獻直接相加就是整體陣列的逆序數。(如果沒有t的制約關係對於乙個逆序對的兩個數都會算一次)減去每個數對陣列的貢獻就是刪去這個位置後的陣列逆序數。

這就轉化為了cdq的模板題了。。cdq**短,時間空間複雜度都很優秀,相比於樹套樹。。。。。

最後注意的是樹狀陣列不要memset。。

#pragma gcc optimize(2)

#include

using namespace std;

const

int maxn =

5e6+5;

typedef

long

long ll;

const ll mod =

1e9+7;

int case =1;

int n, m;

struct tree

void

update

(int pos,

int val)

} ll query

(int pos)

return res;

}}tree;

int cc[maxn]

;struct nodess[maxn]

, temp[maxn]

;bool cmp1

(node a, node b)

bool cmp2

(node a, node b)

int id[maxn]

;ll res[maxn]

;void

cdq(

int l,

int r)

for(

int i = mid+

1; i <= r; i++

)sort

(temp+

1, temp+

1+cnt, cmp2)

;for

(int i = cnt; i >=

1; i--

)else tree.

update

(temp[i]

.z,1);

}for

(int i =

1; i <= cnt; i++)if

(temp[i]

.flag) tree.

update

(temp[i]

.z,-1)

;for

(int i =

1; i <= cnt; i++

)else tree.

update

(temp[i]

.z,1);

}for

(int i =

1; i <= cnt; i++)if

(temp[i]

.flag) tree.

update

(temp[i]

.z,-1)

;}void

solve()

for(

int i =

1; i <= n; i++

)sort

(ss+

1, ss+

1+n, cmp1)

;cdq(1

, n)

; ll sum =0;

for(

int i =

1; i <= n; i++

) sum +

= res[i]

;for

(int i = n; i >= n-m+

1; i--

)return;}

intmain()

return0;

}

另外cdq的**也可以這樣寫,感覺這樣比較正宗。。。。

void

cdq(

int l,

int r)

for(

int i = l; i < ii; i++

) tree.

update

(ss[i]

.z,-1)

; ii = mid, jj = r;

while

(jj >= mid+1)

for(

int i = mid; i > ii; i--

) tree.

update

(ss[i]

.z,-1)

;}

Cqoi2011 動態逆序對

主席樹套樹狀陣列。主席樹第一題。鏈結靜態的逆序對問題很簡單,用線段樹或者是樹狀陣列即可解決。現在的問題是如何解決一道動態的逆序對問題?我們先把所有的逆序對統計出來。每次刪除數,我們可以把這個數對於逆序對個數的貢獻刪除出去。這個貢獻如何統計呢?front i 記錄i位置之前有多少個數比這個數大 bac...

CQOI2011 動態逆序對

這是一道cdq分治的好題,這道題的前置知識是cdq分治解決三維偏序問題,如果不會這個話請先自行學習。首先第乙個答案很顯然就是逆序對的數量,然後後面每次的刪除操作,我們考慮把這個被刪除的點原先的貢獻從答案中拿掉。我們用y表示這個點的數,del表示第幾個被刪除,若沒有被刪除則del m 1 考慮每個點的...

CQOI2011 動態逆序對

點此看題 考慮c dq cdqcd q,有三個值 t,d,v t,d,v t,d,v 要求t i t iti d i d idi v i vj v i v j vi vj 很容易看出來是三維偏序的板題,我們先保證t tt的有序,cdq cdqcd q的時候排序d dd,然後用樹狀陣列查詢v vv,貼...