P3157 CQOI2011 動態逆序對

2021-10-07 22:58:07 字數 1829 閱讀 6718

題目描述

現在給出 1∼n 的乙個排列,按照某種順序依次刪除 m 個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。

輸入格式

第一行包含兩個整數 n和 m,即初始元素的個數和刪除的元素個數。

以下 n 行,每行包含乙個 1∼n 之間的正整數,即初始排列。

接下來 m 行,每行乙個正整數,依次為每次刪除的元素。

輸出格式

輸出包含 m 行,依次為刪除每個元素之前,逆序對的個數。

cdq分治求解動態逆序對,即在有刪除操作的情況下求逆序對數,出座標、數值外,把時間作為第三個維度,即可轉換為三維偏序問題。

把從前往後刪除轉換為從後往前增加,然後每加入乙個點,求兩部分,一部分座標小於值大於,另一部分座標大於值小於,關鍵點在於第三維,若要形成逆序對,時間這一維必須大於。相當於做了兩遍cdq分治。

參考有個地方要注意a[0][b[x]].x=a[1][b[x]].x=m+1-i;不是a[0][x].x=a[1][x].x=m+1-i;我調了一晚上這個bug。

#include

#define lowbit(x) x&(-x)

using

namespace std;

typedef long

long ll;

const ll maxn=

1e5+10;

ll tree[maxn]

;ll ans[maxn]

;ll b[maxn]

;struct nodea[2]

[maxn]

;bool

cmpx

(node a,node b)

bool

cmpy

(node a,node b)

void

update

(ll x,ll val)

}ll query

(ll x)

return sum;

}void

cdq(ll l,ll r,ll wc)

ll mid=

(l+r)

>

>1;

cdq(l,mid,wc)

;cdq

(mid+

1,r,wc)

;sort

(a[wc]

+l,a[wc]

+mid+

1,cmpy)

;sort

(a[wc]

+mid+

1,a[wc]

+r+1

,cmpy)

; ll j=l;

for(ll i=mid+

1;i<=r;i++

) a[wc]

[i].ans+

=query

(a[wc]

[i].z-1)

;}for(ll i=l;iintmain()

for(ll i=

1;i<=m;i++

)sort

(a[0]+

1,a[0]

+1+n,cmpx)

;sort

(a[1]+

1,a[1]

+1+n,cmpx)

;cdq(1

,n,0);

cdq(

1,n,1)

;for

(ll i=

1;i<=n;i++

) ans[0]

/=2;

for(ll i=

1;i<=m;i++

)for

(ll i=m;i>=

1;i--

)}

P3157 CQOI2011 動態逆序對

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

P3157 CQOI2011 動態逆序對

傳送門 設 val i 為位置 i 的值 維護 ansl i 表示位置 i 的數左邊所有大於 val i 的數的數量 維護 ansr i 表示位置 i 的數右邊所有小於 val i 的數的數量 考慮先求出一開始總的逆序對數 ans 每次刪除乙個數 位置為 p 就把 ans 減去 ansl p ans...

洛谷 P3157 CQOI2011 動態逆序對

對於序列a,它的逆序對數定義為滿足iaj的數對 i,j 的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。可以值域分塊,塊套樹狀陣列,樹套樹 不過用序列分塊 vector 一樣能水過這道題 考慮刪去乙個點 x 對答案產生的影響,拿下面的...