還是比較模板的題可是一開始沒想出來。。之前電科校賽就遇到這道原題,今天終於補上了。。
主要的思路還是計算出每個數對前面和後面的影響,然後刪除的時候用總的減去就好了。。
但是問題在於,對於刪除操作怎麼動態的維護前後關係:當刪除乙個數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,貼...