P3157 CQOI2011 動態逆序對

2022-03-04 03:29:24 字數 1779 閱讀 1115

對於序列a,它的逆序對數定義為滿足iaj的數對(i,j)的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。

輸入格式:

輸入第一行包含兩個整數n和m,即初始元素的個數和刪除的元素個數。以下n行每行包含乙個1到n之間的正整數,即初始排列。以下m行每行乙個正整數,依次為每次刪除的元素。

輸出格式:

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

輸入樣例#1:

5 415

3425

142

輸出樣例#1:

522

1樣例解釋

(1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。

n<=100000 m<=50000

solution:

本題帶修改主席樹板子。

離散都不需要,直接對每個位置構建主席樹,先求出逆序對個數,然後每次刪數直接樹狀陣列套主席樹改下,考慮該數被刪去後對逆序對個數的影響,無非就是排在它前面比它大的數的個數+排在它後面比它小的數的個數(提醒我們還得記錄每個數在原序列出現的位置),原逆序對數剪掉這個值就好了。

(注意:本題卡記憶體,我們發現每次主席樹上的修改只與修改前的那棵主席樹有關,而我們查詢只需要當前最新的這棵主席樹,並不需要返回到更之前的樹的情況,所以我們可以**記憶體,每次修改直接覆蓋掉上棵樹的節點就好了。)

**:

/*

code by 520 -- 9.19

*/#include

#define il inline

#define ll long long

#define re register

#define for(i,a,b) for(re int (i)=(a);(i)<=(b);(i)++)

#define bor(i,a,b) for(re int (i)=(b);(i)>=(a);(i)--)

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

using

namespace

std;

const

int n=100005

;int

n,m,a[n],rt[n],cnt,pos[n],x[n],y[n],tx,ty;

struct

nodet[n*120

];struct

bit il

void update(int x,int k)

il int query(int x)

}b;int

gi()

void ins(int l,int r,int k,int x,int lst,int &rt)

il void update(int x,int

v)il

int querysuc(int x,int y,int

v)

else

}return

ans;

}il

int querypre(int x,int y,int

v)

else

}return

ans;

}int

main()

for(i,

1,m)

return0;

}

P3157 CQOI2011 動態逆序對

題目描述 現在給出 1 n 的乙個排列,按照某種順序依次刪除 m 個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。輸入格式 第一行包含兩個整數 n和 m,即初始元素的個數和刪除的元素個數。以下 n 行,每行包含乙個 1 n 之間的正整數,即初始排列。接下來 m 行,每行乙個正整數,依...

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 對答案產生的影響,拿下面的...