zoukankan      html  css  js  c++  java
  • POJ 3667 Hotel(线段树)

    POJ 3667 Hotel

    题目链接

    题意:有n个房间,如今有两个操作
    1、找到连续长度a的空房间。入住,要尽量靠左边,假设有输出最左边的房间标号,假设没有输出0
    2、清空[a, a + b - 1]的房间

    思路:线段树的区间合并。记录下左边连续最长和右边连续最长空房间。和每一段的最大值。这样pushup的时候就是进行区间合并,注意查询的时候因为是要尽量左,所以先查左孩子,在查横跨左右的,在查右孩子

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define lson(x) ((x<<1)+1)
    #define rson(x) ((x<<1)+2)
    
    const int N = 50005;
    
    int n, m;
    
    struct Node {
    	int l, r, lsum, rsum, sum, sumv, lazy;
    	int size() {return r - l + 1;}
    	void gao(int v) {
    		lazy = v;
    		if (v) lsum = rsum = sum = 0;
    		else lsum = rsum = sum = r - l + 1;
    		sumv = l;
    	}
    } node[N * 4];
    
    void pushup(int x) {
    	if (node[lson(x)].lsum == node[lson(x)].size()) node[x].lsum = node[lson(x)].lsum + node[rson(x)].lsum;
    	else node[x].lsum = node[lson(x)].lsum;
    	if (node[rson(x)].rsum == node[rson(x)].size()) node[x].rsum = node[lson(x)].rsum + node[rson(x)].rsum;
    	else node[x].rsum = node[rson(x)].rsum;
    	node[x].sum = node[lson(x)].sum;
    	node[x].sumv = node[lson(x)].sumv;
    	if (node[x].sum < node[lson(x)].rsum + node[rson(x)].lsum) {
    		node[x].sum = node[lson(x)].rsum + node[rson(x)].lsum;
    		node[x].sumv = node[lson(x)].r - node[lson(x)].rsum + 1;
    	}
    	if (node[x].sum < node[rson(x)].sum) {
    		node[x].sum = node[rson(x)].sum;
    		node[x].sumv = node[rson(x)].sumv;
    	}
    }
    
    void pushdown(int x) {
    	if (node[x].lazy != -1) {
    		node[lson(x)].gao(node[x].lazy);
    		node[rson(x)].gao(node[x].lazy);
    		node[x].lazy = -1;
    	}
    }
    
    void build(int l, int r, int x = 0) {
    	node[x].l = l; node[x].r = r; node[x].lazy = -1;
    	if (l == r) {
    		node[x].lsum = node[x].rsum = node[x].sum = 1;
    		return;
    	}
    	int mid = (l + r) / 2;
    	build(l, mid, lson(x));
    	build(mid + 1, r, rson(x));
    	pushup(x);
    }
    
    void add(int l, int r, int v, int x = 0) {
    	if (node[x].l >= l && node[x].r <= r) {
    		node[x].gao(v);
    		return;
    	}
    	int mid = (node[x].l + node[x].r) / 2;
    	pushdown(x);
    	if (l <= mid) add(l, r, v, lson(x));
    	if (r > mid) add(l, r, v, rson(x));
    	pushup(x);
    }
    
    int query(int v, int x = 0) {
    	if (node[x].l == node[x].r) {
    		if (node[x].sum >= v) return node[x].sumv;
    		return 0;
    	}
    	pushdown(x);
    	int ans = 0;
    	if (node[lson(x)].sum >= v)
    		ans = query(v, lson(x));
    	else if (node[lson(x)].rsum + node[rson(x)].lsum >= v) ans = node[lson(x)].r - node[lson(x)].rsum + 1;
    	else if (node[rson(x)].sum >= v)
    		ans = query(v, rson(x));
    	pushup(x);
    	return ans;
    }
    
    int main() {
    	while (~scanf("%d%d", &n, &m)) {
    		build(1, n);
    		int op, a, b;
    		while (m--) {
    			scanf("%d%d", &op, &a);
    			if (op == 2) {
    				scanf("%d", &b);
    				add(a, a + b - 1, 0);
    			} else {
    				int tmp = query(a);
    				printf("%d
    ", tmp);
    				if (tmp == 0) continue;
    				add(tmp, tmp + a - 1, 1);
    			}
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    header
    panel----单个基础版
    vue-demo
    js不同类型变量比较
    reset.css
    关于各个浏览器的兼容问题
    git
    AMD与CMD区别
    喜欢前端的看过来哦
    js中数组去重的几种方法
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6782635.html
Copyright © 2011-2022 走看看