bzoj3295 動態逆序對(CDQ分治)

2021-08-25 17:31:18 字數 1553 閱讀 8555

time limit: 10 sec  memory limit: 128 mb

submit: 7178  solved: 2548

[submit][status][discuss]

對於序列a,它的逆序對數定義為滿足iaj的數對(i,j)的個數。給1到n的乙個排列,按照某種順序依次刪

除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數

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

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

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

n<=100000 m<=50000

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

5 4153

4251

4252

21思路:這是一道十分經典的題目。可以用cdq分治做,也可以用樹套樹做。不過做樹套樹身體會被掏空的,還是cdq好了。。。

之前一直不太了解cdq分治,雖然聽說過它的威名,卻一直沒能學會。今天突擊了一下,算是剛入了點門吧(可能連門都沒入) 

如同網上大佬們所說的,一般三維的cdq問題,第一位排序,第二維分治,第三位資料結構(bit)。。。

本蒟蒻就照著這個做了。不過之前一直沒能理解別人的**中額外開乙個陣列記錄是什麼意思,後來在汪聚聚的講解下明白了這是歸併操作(話說我是不是學了個假的分治。。。)

這道題具體思路可以看: 

主要思想就是將每個點抽象成乙個三元組(位置,數,時間戳)。而上面的做法的巧妙之處在於將刪點轉化為加點(時間戳反向就行了)。所以這道題變成了第一位排序時間戳,第二維cdq位置,第三維用bit位數它前面的數。由於每個點要統計前面和後面的點,所以要跑兩次cdq。。。

**:

#includeusing namespace std;

typedef long long ll;

const int maxn=1e5+10;

typedef struct

c;c c[maxn];

int pos[maxn];

c res[maxn];

ll tot=0;

ll mx;

int n,m;

bool cmp1(c a, c b)

res[++tot]=c[i];

ans[c[i].t]+=ask(c[i].x+1);

} for(int i=l;ifor(int i=ptr;i<=m;i++)

res[++tot]=c[i];

for(int i=l;i<=r;i++) }

int main()

for(int i=1;i<=m;i++)

sort(c+1,c+1+n,cmp1);

solve(1,n);

for (int i=1;i<=n;++i)

sort(c+1,c+1+n,cmp1);

solve(1,n);

for(int i=1;i<=n;i++)

for(int i=1;i<=m;i++)

return 0;

}

bzoj3295 動態逆序對

portal bzoj3295 雖然說這個可能原本是一道愉快的樹套樹但是 看到 按照某個順序依次刪除 這樣的字眼,比較容易聯想到乙個套路 反過來看,變成按照某個順序依次插入 那麼對於乙個詢問,刪掉它之前 化完了之後就是插入它之後 的所會影響到的逆序對數可以分為兩種 一種是在它前面但是比它大的,一種是...

BZOJ3295 動態逆序對

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

BZOJ3295 動態逆序對(樹狀陣列套線段樹)

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