D. Multiset(树状数组 + 二分)
生活随笔
收集整理的這篇文章主要介紹了
D. Multiset(树状数组 + 二分)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Multiset
可能更好的閱讀體驗
思路
二分 + 樹狀數(shù)組做法
我們發(fā)現(xiàn)每個數(shù)的范圍是$ <= 1e6$的,所以可以直接在線操作,不用離散化離線操作。
這個時候我們的treetreetree數(shù)組就相當與一個桶,每個桶里統(tǒng)計的是值為其下標的個數(shù),通過樹狀數(shù)組的前綴和性質,我們可以通過二分輕松的鎖定第kkk項的位置,然后進行刪除操作,具體的操作細節(jié)看代碼實現(xiàn)。
權值線段樹做法
線段相較而言,常數(shù)大一些,維護的基本思路還是更樹狀數(shù)組是一樣的。當我樹狀數(shù)組1122ms1122 ms1122ms過了之后,感覺線段樹有點懸,然后就沒寫了,這里只是提供一個思路。
代碼
#include <bits/stdc++.h>using namespace std;typedef long long ll; const int N = 1e6 + 10;int tree[N], n, m;inline ll read() {ll x = 1, s = 0; char c;c = getchar();while(c < '0' || c > '9') {if(c == '-') x = -1;c = getchar();}while(c >= '0' && c <= '9') {s = (s << 1) + (s << 3) + (c ^ 48);c = getchar();}return x * s; }inline int lowbit(int x) {return (-x) & (x); }inline void add(int x, int value) {while(x <= n) {tree[x] += value;x += lowbit(x);} }inline int get_sum(int x) {int sum = 0;while(x) {sum += tree[x];x -= lowbit(x);}return sum; }int main() {// freopen("in.txt", "r", stdin);n = read(), m = read();for(int i = 1; i <= n; i++) {int x = read();add(x, 1);}// for(int i = 1; i <= n; i++)//調試用的,可以不管。// printf("%d%c", get_sum(i), i == n ? '\n' : ' ');for(int i = 1; i <= m; i++) {int x = read();if(x > 0) add(x, 1);//插入操作簡單,只需要修改其數(shù)組下標就行。else {x = abs(x);int l = 1, r = n;while(l < r) {//找到第一個其前綴和大于等于k的下標,修改其值。int mid = l + r >> 1;if(get_sum(mid) >= x) r = mid;else l = mid + 1;}add(l, -1);}// for(int i = 1; i <= n; i++)// printf("%d%c", get_sum(i), i == n ? '\n' : ' ');}int l = 1, r = n;while(l < r) {//尋找第一個大于等于一的下標,其下標就是在集合中一定存在的數(shù)。int mid = l + r >> 1;if(get_sum(mid) >= 1) r = mid;else l = mid + 1;}if(get_sum(l) >= 1) printf("%d\n", l);//特判一下查找結果。else puts("0");return 0; }總結
以上是生活随笔為你收集整理的D. Multiset(树状数组 + 二分)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 派瑞松软膏的作用与功效
- 下一篇: 点分治(简要讲解 + 模板)