P1908 逆序對 樹狀陣列解法)

2022-05-26 22:57:08 字數 1434 閱讀 9046

題目描述

貓貓 tom 和小老鼠 jerry 最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。

最近,tom 老貓查閱到乙個人類稱之為「逆序對」的東西,這東西是這樣定義的:對於給定的一段正整數序列,逆序對就是序列中 ai>aja_i>a_ja

i​>a

j​ 且 ii

update:資料已加強。

輸入格式

第一行,乙個數 nnn,表示序列中有 nnn個數。

第二行 nnn 個數,表示給定的序列。序列中每個數字不超過 10910^9109。

輸出格式

輸出序列中逆序對的數目。

輸入輸出樣例

輸入#1複製

65 4 2 6 3 1

輸出#1複製

11這個題可以用線段樹寫,但樹狀陣列寫起來更優雅一些。資料加強後可以作為樹狀陣列+離散化的板子題了。看到資料範圍我們知道常規的桶肯定是不行的,1e9直接mle,那麼需要離散化一下。這裡我用的是結構體儲存原數和其初始位置,然後對結構體陣列從小到大sort一遍。此時開闢乙個新的陣列rank。比較關鍵的部分是:

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

rank[p[i].x]=i;

rank陣列也相當乙個桶,只不過桶的大小不必為1e9了,只需5e5即可。這樣得到的新的rank陣列實際上和原陣列是等價的,只不過數的絕對大小變成了相對大小。然後利用樹狀陣列處理。但這樣其實有乙個問題,就是資料可能是重複的。解決方法有2:一是用stable_sort排序,外加cmp函式裡取等號;二是cmp函式中如果兩個結構體數值相等,那麼按照位置大小排序。這樣的話即使兩個數相等,也會使得分配後的大小能確保不會對逆序數的計算產生影響。

#include using

namespace

std;

int ans=0

,n,i;

int t[500005],rank[500005

];struct

point

p[500005

];bool

cmp(point a, point b)

void add(int x, int

y)int ask(int

x)int

main()

sort(p + 1, p + n + 1, cmp);//

按照原數排序

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

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

cout

}

P1908 逆序對 樹狀陣列

p1908 題目描述 貓貓 tom 和小老鼠 jerry 最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。最近,tom 老貓查閱到乙個人類稱之為 逆序對 的東西,這東西是這樣定義的 對於給定的一段正整數序列,逆序對就是序列中 ai aj且 iupdate...

P1908 逆序對 (樹狀陣列)

比較喜歡線段樹,懶得用樹狀陣列 只會套模板,位運算的精髓沒有領悟到 一直沒有記錄樹狀陣列 又得撿回來,趁這道題記錄一下模板,為三維偏序cdq套樹狀陣列鋪墊一下。解題思路 先對原陣列a從大到小排序,依次新增進樹狀陣列c裡,每次求字首和的結果就是 當前數的逆序對的個數。例如資料 55,44,22,66,...

洛谷P1908 逆序對(樹狀陣列)

題目描述 貓貓tom和小老鼠jerry最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。最近,tom老貓查閱到乙個人類稱之為 逆序對 的東西,這東西是這樣定義的 對於給定的一段正整數序列,逆序對就是序列中ai aj且i輸入輸出格式 輸入格式 第一行,乙個數...