【线段树维护区间编号 && 区间更新】HDU
来源:互联网 发布:新疆网络安全形势 编辑:程序博客网 时间:2024/05/24 02:27
Problem Description
输入T,代表有T组测试数据。每组测试数据输入n, m。分别代表有n个花瓶,编号为0-(n-1)。接下里有m行操作:分为两种操作。
(1) : 1 x y :从第x个花瓶开始往后放y朵花。有位置就放,没位置就跳过,直到放完或者超过n-1 同时 返回最开始放的花瓶编号和最后放的花瓶编号如果一朵也放不了就返回”Can not put any one.”。(2) : 2 x y : 询问第x个花瓶到第y个花瓶有多少朵花,同时将花清空
思路:
用线段树维护区间中第一个空花瓶的位置ll,最后一个空花瓶的位置rr。data维护区间还有几个空花瓶。lazy标记0代表该区间没动过,1表示区间全为花,2代表区间全空。详细操作看代码,个人习惯从1开始,所以结果都得-1,输入许多东西也得+1
#include<bits/stdc++.h>using namespace std;struct node{ int data, lazy, ll, rr;};#define inf 0x3f3f3f3f#define N 50001#define lson root<<1#define rson root<<1|1#define MID int mid = (l + r) / 2node a[N<<2];int k, Min, Max;void build(int root, int l, int r)//初始化,一开始全为空{ a[root].ll = l; a[root].rr = r;//第一个空花瓶位置,最后一个空花瓶位置 a[root].data = (r - l) + 1;//空花瓶的数量 a[root].lazy = 0; if(l == r) return; MID; build(lson, l, mid); build(rson, mid + 1, r);}node Merge(node x, node y)//区间归并{ node res; res.lazy = 0; res.data = x.data + y.data;//空花瓶数量求和 res.ll = min(x.ll, y.ll);//第一个空花瓶 res.rr = max(x.rr, y.rr);//最后一个空花瓶 return res;}void pushdown(int root, int l, int r){ if(a[root].lazy == 1)//全有花,向下更新 { a[lson].lazy = a[rson].lazy = a[root].lazy; a[lson].ll = a[rson].ll = a[root].ll; a[rson].rr = a[lson].rr = a[root].rr; a[lson].data = a[rson].data = a[root].data;//等于0 a[root].lazy = 0; } else if(a[root].lazy == 2)//全没花,向下更新 { MID; a[lson].lazy = a[rson].lazy = a[root].lazy; a[lson].ll = l; a[lson].rr = mid;//相当于初始化 a[rson].ll = mid + 1; a[rson].rr = r; a[lson].data = (mid - l + 1); a[rson].data = (r - (mid + 1) + 1); a[root].lazy = 0; }}void updata(int root, int l, int r, int ul, int ur)//更新第ul花瓶开始后面填k个花{ if(ul <= l && r <= ur) { if(k >= a[root].data)//填的花数大于当前区间空花瓶树 { k -= a[root].data;//更新k a[root].data = 0; a[root].lazy = 1;//为1,代表全为花 Min = min(Min, a[root].ll);//更新放的第一个花瓶 Max = max(Max, a[root].rr);//更新放的最后一个花瓶 a[root].ll = inf;//全为花了,就没有空花瓶了。为无穷大 a[root].rr = -inf;//无穷小 return; } else if(l == r) return; } pushdown(root, l, r); MID; if(ul <= mid && k) updata(lson, l, mid, ul, ur); if(ur > mid && k) updata(rson, mid + 1, r, ul, ur); a[root] = Merge(a[lson], a[rson]);}int query(int root, int l, int r, int ul, int ur)//返回red,同时更新全为空{ int red = 0; if(ul <= l && r <= ur) { red = a[root].data; a[root].data = (r - l + 1);//更新全为空花瓶 a[root].lazy = 2;//标记 a[root].ll = l; a[root].rr = r;//初始化 return a[root].data - red;//花瓶数-空花瓶数。为清空的花瓶数 } pushdown(root, l, r); MID; if(ul <= mid) red += query(lson, l, mid, ul, ur); if(ur > mid) red += query(rson, mid + 1, r, ul, ur); a[root] = Merge(a[lson], a[rson]); return red;}int main(){ int T, n, m, ok, ul, ur; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); build(1, 1, n); while(m--) { scanf("%d %d %d", &ok, &ul, &ur); if(ok == 1) { ul++; k = ur; Min = inf; Max = -inf; updata(1, 1, n, ul, n); if(Min == inf && Max == -inf) printf("Can not put any one.\n");//ul往后代表全满了。 else printf("%d %d\n", Min - 1, Max - 1); } else { ul++; ur++; printf("%d\n", query(1, 1, n, ul, ur)); } } printf("\n"); } return 0;}
阅读全文
0 0
- 【线段树维护区间编号 && 区间更新】HDU
- HDU 4302 线段树单点更新,维护区间最大最小值
- poj 3468 线段树区间更新维护
- poj3237(树链剖分边维护+线段树区间更新)
- hdu 5023(线段树区间更新+区间查询)
- 线段树--区间更新-区间查询HDU 1698
- hdu 5239 区间平方 线段树区间更新
- HDU 1698 区间更新线段树
- hdu 3308 线段树 区间更新 LICS
- HDU 3308 LCIS 线段树区间更新
- hdu 4578 Transformation [线段树 区间更新]
- hdu 1698 线段树区间更新
- hdu 3308 线段树区间更新
- hdu 2795 线段树,区间更新求补值
- HDU 1698 【线段树区间更新】
- HDU 1698(线段树区间更新)
- hdu 1698 线段树 区间更新
- HDU 1698 线段树区间更新模板
- C语言 函数
- ssh远程copy文件报not a regular file错误
- Linux常用命令
- BIND9源码学习笔记1---gdb调试篇
- AngularJS的数据双向绑定是怎么实现的?
- 【线段树维护区间编号 && 区间更新】HDU
- Hive:hive is not allowed to impersonate anonymous
- VLAN原理详解[转载] 网桥--交换机---路由器
- 自定义view之layout()与onLayout()方法
- lightoj1017 Brush (III) (dp)
- 【HDU 1070】Milk(贪心)
- C++ Primer Notes(13)
- linux下 Mysql的安装
- 【leetcode】2. Add Two Numbers(Python & C++)