在平面上進行三種操作:
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 #include #define lowbit(x) ((x)&(-(x)))
#define lson (step<<1)
#define rson (step<<1|1)
using namespace std;
const int n = 200005;
struct query
}ask[n];
struct seg_treel[n<<2];
int m,q,x[n];
sets[n];
void bulid(int step,int l,int r)
inline void push_up(int step)
void update(int step,int pos)
int m=(l[step].left+l[step].right)>>1;
if(pos<=m) update(lson,pos);
else update(rson,pos);
push_up(step);
}int query(int step,int l,int r,int y)
}int main(){
scanf("%d",&q);
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每個數,當前數字在原陣列位置前不能有更小的未被消去的值...