HDU 5649 二分 線段樹

2021-07-23 19:40:01 字數 1456 閱讀 8011

題意:給出乙個排列,每次操作[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...