點此看題
考慮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,貼乙個有注釋的**。
#include
#include
using
namespace std;
const
int m =
150005
;int
read()
int n,m,k,a[m]
,pos[m]
,bit[m]
;long
long ans[m]
;struct node
}p[m]
;int
lowbit
(int x)
void
ins(
int x,
int f)
intask
(int x)
void
cdq(
int l,
int r)
ans[p[i]
.id]
+=p[i]
.tp*
(ask
(k)-
ask(p[i]
.v));}
for(j--
;j>=l;j--
)ins
(p[j]
.v,-p[j]
.tp)
; j=mid;
for(
int i=r;i>mid;i--
) ans[p[i]
.id]
+=p[i]
.tp*
ask(p[i]
.v-1);
}for
(j++
;j<=mid;j++
)ins
(p[j]
.v,-p[j]
.tp);}
intmain()
;}for(
int i=
1;i<=m;i++);
}cdq(1
,n);
for(
int i=
1;i) ans[i]
+=ans[i-1]
;for
(int i=
0;i)printf
("%lld\n"
,ans[i]);
}
Cqoi2011 動態逆序對
主席樹套樹狀陣列。主席樹第一題。鏈結靜態的逆序對問題很簡單,用線段樹或者是樹狀陣列即可解決。現在的問題是如何解決一道動態的逆序對問題?我們先把所有的逆序對統計出來。每次刪除數,我們可以把這個數對於逆序對個數的貢獻刪除出去。這個貢獻如何統計呢?front i 記錄i位置之前有多少個數比這個數大 bac...
CQOI2011 動態逆序對
這是一道cdq分治的好題,這道題的前置知識是cdq分治解決三維偏序問題,如果不會這個話請先自行學習。首先第乙個答案很顯然就是逆序對的數量,然後後面每次的刪除操作,我們考慮把這個被刪除的點原先的貢獻從答案中拿掉。我們用y表示這個點的數,del表示第幾個被刪除,若沒有被刪除則del m 1 考慮每個點的...
CQOI2011 動態逆序對
使用樹狀陣列求出初態下出f i g i 表示位置小 大 於i且值大 小 於a i 的元素個數。顯然ans 初 sum f i sum g i 考慮第乙個刪去的點x,刪去以後,ans減少f x g x 再考慮第二個刪去的點y,刪去以後,ans減少f y g y 不,f y g y 中可能算上了x 此題...