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 ...