題意:給出乙個排列,每次操作[l,r]區間的數原地公升序或者降序,詢問最後k下標的數。
二分最後的結果mid,然後把比mid大的換成1,小於等於mid的換成0,那麼公升序降序相當於求出區間中0的個數然後把前半段和後半段分別用0\1覆蓋。這樣只需要維護乙個區間查詢,區間修改的線段樹即可。
#include
#include
#include
#include
#include
using
namespace
std;
#define pl c<<1
#define pr (c<<1)|1
#define lson tree[c].l,tree[c].mid,pl
#define rson tree[c].mid+1,tree[c].r,pr
#define maxn 100005
struct node tree[maxn<<3];
int op[maxn][3];
int a[maxn], b[maxn];
int n, m, k;
void build_tree (int l, int r, int c)
build_tree (lson);
build_tree (rson);
tree[c].num = tree[pl].num + tree[pr].num;
}void push_down (int c)
else
if (tree[c].one)
}void update (int l, int r, int c, int x, int y, int op)
else
return ;
}if (tree[c].mid >= y) update (lson, x, y, op);
else
if (tree[c].mid < x) update (rson, x, y, op);
else
tree[c].num = tree[pl].num+tree[pr].num;
tree[c].zero = tree[c].one = 0;
}int query (int l, int r, int c, int x, int y)
if (tree[c].mid >= y)
else
if (tree[c].mid < x)
else
}bool ok (int x)
else
}int res = query (1, n, 1, k, k);
return res^1;
}int main ()
printf ("%d\n", ok (l) ? r : l);
}return
0;}
HDU 5649 線段樹 二分
n個數的排列,兩種操作,一種將 l,r 區間內的數遞減排序,另一種將 l,r 中的數遞增排序,問最後第k個位置的數字是多少。好題。因為最後考慮的只是第k個位置的數字,二分答案。每次將序列中比x大的都標記為1,其餘包括x標記為0,每次排序前,先查詢區間中有多少個1和0,然後按照操作將1和0分別更新到區...
hdu4614 二分 線段樹
題意 給你1 n的花瓶 剛開始全是空的,現在有兩種操作,1 從花瓶a開始插入b朵花 如果不能插進去 輸出字串 否則輸出最多插入的起點和終點 結構體陣列num i 表示節點i空瓶的數目 線段樹 開始deal函式對整個樹初始化,update 更新函式 find 查詢區間有多少個空瓶 對於操作1 關鍵點是...
b vj K th Number(二分 線段樹)
有乙個數列a 1 n 中 數字各不相同 輸入m行i,j,k,目的是求a i.j 之間第k小的數 includeusing namespace std typedef long long ll const int n 1e6 5 ll n,m,a n vectort n void pushup int...