1. 程式人生 > >線段樹區間合並(模板)

線段樹區間合並(模板)

pan 技術 cst view -- cli scanf 線段樹 sed

poj3667

技術分享圖片
#include<cstdio>
#include<algorithm>
#define lid id << 1
#define rid id << 1 | 1
using namespace std;

const int mx = 50010;

struct tree{
    int l, r;
    int ls, rs, ms;
    int lazy;
}tree[mx<<2];

void build(int l, int r, int id){
    tree[id].l 
= l; tree[id].r = r; tree[id].ls = tree[id].rs = tree[id].ms = r-l+1; tree[id].lazy = -1; if (l == r) return; int mid = (l+r) >> 1; build(l, mid, lid); build(mid+1, r, rid); } void pushdown(int id){ if (tree[id].lazy != -1){ tree[lid].lazy = tree[rid].lazy = tree[id].lazy; tree[lid].ls
= tree[lid].rs = tree[lid].ms = tree[id].lazy ? 0 : tree[lid].r-tree[lid].l+1; tree[rid].ls = tree[rid].rs = tree[rid].ms = tree[id].lazy ? 0 : tree[rid].r-tree[rid].l+1; tree[id].lazy = -1; } } void pushup(int id){ tree[id].ls = tree[lid].ls; tree[id].rs = tree[rid].rs;
int mid = (tree[id].l + tree[id].r) >> 1; if (tree[id].ls == mid-tree[id].l+1) tree[id].ls += tree[rid].ls; if (tree[id].rs == tree[id].r-mid) tree[id].rs += tree[lid].rs; tree[id].ms = max(max(tree[lid].ms, tree[rid].ms), tree[lid].rs+tree[rid].ls); } void upd(int l, int r, int id, bool x){ if (tree[id].l == l && tree[id].r == r){ tree[id].lazy = x; tree[id].ls = tree[id].rs = tree[id].ms = x ? 0 : r-l+1; return; } pushdown(id); int mid = (tree[id].l + tree[id].r) >> 1; if (r <= mid) upd(l, r, lid, x); else if (mid < l) upd(l, r, rid, x); else { upd(l, mid, lid, x); upd(mid+1, r, rid, x); } pushup(id); } int query(int l, int r, int id, int x){ if (l == r) return l; pushdown(id); int mid = (l+r) >> 1; if (tree[lid].ms >= x) return query(l, mid, lid, x); else if (tree[lid].rs + tree[rid].ls >= x) return mid-tree[lid].rs+1; return query(mid+1, r, rid, x); } int main(){ int n, m; scanf("%d%d", &n, &m); build(1, n, 1); while (m--){ int op, a, b; scanf("%d%d", &op, &a); if (op == 1){ if (tree[1].ms < a) printf("0\n"); else { b = query(1, n, 1, a); printf("%d\n", b); upd(b, b+a-1, 1, 1); } } else { scanf("%d", &b); upd(a, a+b-1, 1, 0); } } return 0; }
View Code

線段樹區間合並(模板)