poj 3667线段树区间合并

    xiaoxiao2024-07-27  8

    题意:有很多房间,每次客人来住的时间要连续的房间,多次操作查询。

    分析:维护prefix和suffix数组来表示一段区间连续的个数

    具体实现详见代码:

    #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define lson l , mid , rt << 1 #define rson mid + 1, r, rt << 1 | 1 using namespace std; const int maxn = 4e5 +20; struct InterxTree { int prefix[maxn],suffix[maxn],sum[maxn],set[maxn]; void build(int l, int r, int rt) { set[rt] = -1; prefix[rt] = suffix[rt] = sum[rt] = r - l + 1; if(l == r) return ; int mid = (l + r) >> 1; build(lson); build(rson); } void pushdown(int rt ,int k) { if(~set[rt]) { set[rt<<1] = set[rt<<1|1] = set[rt]; prefix[rt<<1] = suffix[rt<<1] = sum[rt<<1] = set[rt] ? 0 : k - (k>>1); prefix[rt<<1|1] = suffix[rt<<1|1] = sum[rt<<1|1] = set[rt] ? 0 : (k>>1); set[rt] = -1; } } void maintain(int rt ,int k) { suffix[rt] = suffix[rt<<1|1]; prefix[rt] = prefix[rt<<1]; if(prefix[rt<<1] == k - (k>>1)) prefix[rt] += prefix[rt<<1|1]; if(suffix[rt<<1|1] == (k>>1)) suffix[rt] += suffix[rt<<1]; sum[rt] = max(suffix[rt<<1] + prefix[rt<<1|1] , max(sum[rt<<1],sum[rt<<1|1])); } void update(int L, int R, int v, int l, int r, int rt) { if(L <= l && r <= R) { prefix[rt] = suffix[rt] = sum[rt] = v ? 0 : r - l + 1; set[rt] = v; return ; } pushdown(rt , r - l + 1); int mid = (l + r) >> 1; if(L <= mid) update(L, R , v, lson); if(R > mid) update(L, R , v, rson); maintain(rt , r - l + 1); } int query(int v, int l, int r, int rt) { if(l == r) return l; if(set[rt] == 0) return l; int mid = (l + r) >> 1; if(sum[rt<<1] >= v) return query(v, lson); else if(suffix[rt<<1] + prefix[rt<<1|1] >= v) return mid - suffix[rt<<1] + 1; else return query(v, rson); } }tree; int main(void) { freopen("1.txt","r",stdin); int n,m; while(~scanf("%d%d",&n,&m)) { tree.build(1,n,1); int a,b,c; while(m--) { scanf("%d",&a); if(a==1) { scanf("%d",&b); if(tree.sum[1] < b) { printf("0\n"); } else { int pos = tree.query(b , 1, n, 1); printf("%d\n",pos); tree.update(pos,pos + b - 1, 1, 1, n, 1); } } else { scanf("%d%d",&b,&c); tree.update(b, b + c - 1, 0, 1, n, 1); } } } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-1291091.html
    最新回复(0)