BZOJ 3289 Mato的檔案管理

2022-04-30 11:21:10 字數 1690 閱讀 7928

time limit: 40 sec  memory limit: 128 mb

submit: 2368  solved: 971

[submit][status][discuss]

mato同學從各路神犇以各種方式(你們懂的)收集了許多資料,這些資料一共有n份,每份有乙個大小和乙個編號。為了防止他人偷拷,這些資料都是加密過的,只能用mato自己寫的程式才能訪問。mato每天隨機選乙個區間[l,r],他今天就看編號在此區間內的這些資料。mato有乙個習慣,他總是從檔案大小從小到大看資料。他先把要看的檔案按編號順序依次拷貝出來,再用他寫的排序程式給檔案大小排序。排序程式可以在1單位時間內交換2個相鄰的檔案(因為加密需要,不能隨機訪問)。mato想要使檔案交換次數最小,你能告訴他每天需要交換多少次嗎?

第一行乙個正整數n,表示mato的資料份數。

第二行由空格隔開的n個正整數,第i個表示編號為i的資料的大小。

第三行乙個正整數q,表示mato會看幾天資料。

之後q行每行兩個正整數l、r,表示mato這天看[l,r]區間的檔案。

q行,每行乙個正整數,表示mato這天需要交換的次數。

41 4 2 3

21 2

2 40

2hint

n,q <= 50000

樣例解釋:第一天,mato不需要交換

第二天,mato可以把2號交換2次移到最後。

by taorunz

[submit][status][discuss]

小生的第二道莫隊演算法。易知一段區間內的最小交換次數就是這段區間內的逆序對數,這個可以通過用樹狀陣列動態維護。樹狀陣列是按權值組織的,當在區間右側新加入乙個元素時,新形成的逆序對數就是前面區間中嚴格大於該元素的元素個數,反之亦然,請客官自行推導吧(ノ*・ω・)ノ。

1 #include 2

3 template

4 inline void read(t &num)

1314 num = 0;15

16while (bit >= '0'

) 21

22if (neg)num = -num;23}

2425

const

int siz = 50005;26

27int

n, m, s, num[siz], tmp[siz], bit[siz], answer;

2829

struct

query qry[siz];

3233 inline bool cmp_lr(const query &a, const query &b)

3940 inline bool cmp_id(const query &a, const query &b)

4344 inline void add(int k, int

v) 47

48 inline int ask(int

k) 53

54 signed main(void

) 85

86 std::sort(qry + 1, qry + 1 +m, cmp_id);

8788

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

89 printf("

%d\n

", qry[i].ans);

90 }

@author: yousiki

bzoj3289 Mato的檔案管理

給定乙個序列,每次詢問乙個區間,你可以交換相鄰兩個元素,這個區間你最少需要多少次交換才能使其有序。我們觀察,每次交換如果交換a i 和a i 1 那麼顯然a i a i 1 交換後逆序對個數減一。當序列逆序對個數為0時序列就有序。那麼顯然題意就是詢問區間逆序對個數。我們可以用莫隊演算法來做。因為它符...

bzoj 3289 Mato的檔案管理

description mato同學從各路神犇以各種方式 你們懂的 收集了許多資料,這些資料一共有n份,每份有乙個大小和乙個編號。為了防止他人偷拷,這些資料都是加密過的,只能用mato自己寫的程式才能訪問。mato每天隨機選乙個區間 l,r 他今天就看編號在此區間內的這些資料。mato有乙個習慣,他...

bzoj3289 Mato的檔案管理

description mato同學從各路神犇以各種方式 你們懂的 收集了許多資料,這些資料一共有n份,每份有乙個大小和乙個編號。為了防止他人偷拷,這些資料都是加密過的,只能用mato自己寫的程式才能訪問。mato每天隨機選乙個區間 l,r 他今天就看編號在此區間內的這些資料。mato有乙個習慣,他...