在平面上進行三種操作:
1、add x y:在平面上新增乙個點(x,y)
2、remove x y:將平面上的點(x,y)刪除
3、find x y:在平面上尋找乙個點,使這個點的橫座標大於x,縱座標大於y,而且要求他的橫座標盡量小,如果有多個點滿足,則選取橫座標盡量小的前提下,縱座標最小的點。
方法:將橫座標x離散化,每乙個座標x對應的y用一顆平衡樹維護(c++中的set),則這顆平衡樹支援增加和刪除以及查詢比y大的最小值的操作。
在此基礎上,對於每乙個詢問,只需要遍歷大於x的set,並且找到最小的y即可。但是這樣子依次向後遍歷的複雜度為o(n)的,所以要用一顆線段樹來維護橫座標區間段裡面y的最大值,這樣就可以在o(logn)的複雜度內找到最接近x的橫座標(而且滿足當前座標的最大縱座標大於y),然後再set裡面查詢最小的縱座標即可。
#include #include #include #include #include using namespace std;
#define n 200100
int n, m, a[n], my[n<<2];
seta[n];
char s[10];
struct node q[n];
int idx(int v)
void update(int x, int l, int r, int rt)
int mid = (l + r) >> 1;
if (x <= mid) update(x, l, mid, rt<<1);
else update(x, mid+1, r, rt<<1|1);
my[rt] = max(my[rt<<1], my[rt<<1|1]);
}int query(int x, int y, int l, int r, int rt)
int mid = (l + r) >> 1;
int t = 0;
if (x < mid && my[rt<<1] > y) t = query(x, y, l, mid, rt<<1);
if (t == 0 && my[rt<<1|1] > y) t = query(x, y, mid+1, r, rt<<1|1);
return t;
}int main() {
scanf("%d", &n);
m = 0;
for (int i=0; i
CF 19D Points 線段樹 平衡樹
在平面上進行三種操作 1 add x y 在平面上新增乙個點 x,y 2 remove x y 將平面上的點 x,y 刪除 3 find x y 在平面上尋找乙個點,使這個點的橫座標大於x,縱座標大於y,而且要求他的橫座標盡量小,如果有多個點滿足,則選取橫座標盡量小的前提下,縱座標最小的點。方法 將...
cf474e Pillars 線段樹優化dp
有n個柱子,每個柱子有乙個高度hi h i,每個柱子可以跳到它後面高度與它相差大於d的柱子 即 h i hj d hi hj d 求最多可以跳多少個柱子an si m ax a nsj 1 hi h j d且 ja ns i ma x an sj 1 h i hj d且 j 因此建立一棵線段樹,節點...
cf 1187D 逆序對(線段樹)
題意 給你兩個均有n個數的陣列,現在你可以對a陣列中的任意區間進行sort操作,問你在sort完之後能不能得到b陣列。做法 這個是真的想不到啊。想法2200分的題目,大概的意思就是,因為可以對其中的任意區間進行操作,等於是去找逆序對的樣子,for每個數,當前數字在原陣列位置前不能有更小的未被消去的值...