hdu 5193 分塊 樹狀陣列 逆序對

2021-06-29 11:47:20 字數 1801 閱讀 4599

hdu 5193 分塊 樹狀陣列 逆序對

題意:給出n個數,a1,a2,a3,...,an,給出m個修改,每個修改往陣列的某個位置後面插入乙個數,或者把某個位置上的數移除。求每次修改後逆序對的個數。

限制:1 <= n,m <= 20000; 1 <= ai <= n

思路:插入和刪除用分塊來處理,塊與塊之間用雙向鍊錶來維護,每一塊用樹狀陣列來求小於某個數的數有多少個。

外層可以使用分塊維護下標,這樣新增和刪除元素的時候,也很方便,直接暴力。查詢權值個數時,使用樹狀陣列比較方便。內層通過樹狀陣列維護權值。

每次更新即為,在前面塊找比它大和在後面塊中找比它小的代價。

o(m*(sqrt(n)+sqrt(n)*log(n)))

/*hdu 5193 分塊 樹狀陣列 逆序對

題意:給出n個數,a1,a2,a3,...,an,給出m個修改,每個修改往陣列的某個位置後面插入乙個數,或者把某個位置上的數移除。求每次修改後逆序對的個數。

限制:1 <= n,m <= 20000; 1 <= ai <= n

思路:插入和刪除用分塊來處理,塊與塊之間用雙向鍊錶來維護,每一塊用樹狀陣列來求小於某個數的數有多少個。

外層可以使用分塊維護下標,這樣新增和刪除元素的時候,也很方便,直接暴力。查詢權值個數時,使用樹狀陣列比較方便。內層通過樹狀陣列維護權值。

每次更新即為,在前面塊找比它大和在後面塊中找比它小的代價。

o(m*(sqrt(n)+sqrt(n)*log(n)))

*/#include#include#include#include#includeusing namespace std;

#define ll __int64

#define pb push_back

const int n=355;

const int m=20005;

int tot;

vectorvec[n];

int pre[n],nxt[n];

int sz;

int bit[n][m];

int lowbit(int x)

int sum(int i,int x)

return s;

}void update(int i,int x,int w)

for(int i=id;ivec[p].size())

vec[p].insert(vec[p].begin()+id,h);

update(p,h,1);

int left=count_left(p,h);

int right=count_right(p,h);

int in=count_in(p,id,h);

if(vec[p].size()>sz)

else

} return left+in+right;

}int qui(int id)

int h=vec[p][id-1];

int left=count_left(p,h);

int right=count_right(p,h);

int in=count_in(p,id,h);

vec[p].erase(vec[p].begin()+id-1); //

update(p,h,-1);

return left+right+in;

}int main()

} ll ans=merge_count(a);

int cm,x,y;

for(int i=0;ielse

//print();

} }return 0;

}

BZOJ 4765 分塊 樹狀陣列

傳送門 奮戰三星期,造台計算機 小g響應號召,花了三小時造了臺普通計算姬。普通計算姬比普通計算機要厲害一些 普通計算機能計算數列區間和,而普通計算姬能計算樹中子樹和。更具體地,小g的計算姬可以解決這麼個問題 給定一棵n個節點的帶權樹,節點編號為1到n,以root為根,設sum p 表示以點p為根的這...

bzoj2141 分塊套樹狀陣列 樹套樹

題意 動態維護逆序對,每次會交換兩個數。首先離散一波。然後這題其實很顯然,分塊處理先,然後對於每次交換,只有在x,y之間的才有用。那麼在bl x 1和bl y 1之間的數都是整塊,可以直接用bit維護。否則就是乙個塊內的,就可以直接暴力維護了。感覺我的實現姿勢不好,寫的很醜,看了po姐的感覺慚愧。於...

HDU1754 分塊入門1

題意 單點更新,區間求最值 思路 維護每個值 and 分塊,維護每塊的最值 如果 x 和 y 隸屬於同一塊,那麼直接列舉就行 如果它們不在同一塊,那麼中間的每一塊的最大值可以由數列 p 得到,其他x,y各自所在塊包含的元素直接列舉即可 列舉塊數複雜度 sqrt n 列舉塊內元素複雜度 sqrt n ...