HDU 4614 Vases and Flowers(线段树+2分)

来源:互联网 发布:画框图软件 编辑:程序博客网 时间:2024/06/16 02:05
/*
WA了几次,最后原来是把lazy赋值为0并且lazy!=0的时候才需要pushdown的问题
因为有可能把区间全部赋值为0,所以lazy不可以赋值为0
线段树加二分自己写出来了,蛮开心的~~~~
*/
#include <iostream>#include <cstdio>#include<cmath>#pragma warning (disable:4996)using namespace std;const int N = 50001;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define min(a,b) a<b?a:bstruct Node{int l, r;int lazy;int sum;int mid(){return (l + r) >> 1;}} tree[N << 2];void PushUp(int rt){tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;}void PushDown(int rt, int m){if (tree[rt].lazy!=-1)// 这里不能是lazy!=0{tree[rt << 1].lazy = tree[rt].lazy;tree[rt << 1 | 1].lazy = tree[rt].lazy;tree[rt << 1].sum = tree[rt].lazy * (m - (m >> 1));tree[rt << 1 | 1].sum = tree[rt].lazy * (m >> 1);tree[rt].lazy = -1;}}void build(int l, int r, int rt){tree[rt].l = l;tree[rt].r = r;tree[rt].lazy = -1;//这里要把lazy赋值-1或者其他,反正不能是0if (l == r){tree[rt].sum = 0;return;}int m = tree[rt].mid();build(lson);build(rson);PushUp(rt);}void update(int c, int l, int r, int rt){/*如果此时按照常规的线段树的update操作,这时候还应该更新rt子节点的sum值,而Lazy思想恰恰是暂时不更新rt子节点的sum值,到此就return,直到下次需要用到rt子节点的值的时候才去更新*/if (tree[rt].l == l && r == tree[rt].r){tree[rt].lazy = c;//   lazy!=-1表示此节点以下的子节点没有更新,这里如果区间全变为0则lazy=0,所以上面lazy初始化不能为0tree[rt].sum = c * (r - l + 1);return;}if (tree[rt].l == tree[rt].r) return;/*在某部分update操作的时候需要用到那部分没有更新的节点的值的时候需要更新子节点的值这时就调用PushDown()函数更新子节点的数值*/PushDown(rt, tree[rt].r - tree[rt].l + 1);//先给自己的儿子pushdownint m = tree[rt].mid();//再给儿子的儿子pushdown更新if (r <= m) update(c, l, r, rt << 1);else if (l > m) update(c, l, r, rt << 1 | 1);else{update(c, l, m, rt << 1);update(c, m + 1, r, rt << 1 | 1);}PushUp(rt);}int query(int l, int r, int rt){if (l == tree[rt].l && r == tree[rt].r){return tree[rt].sum;}PushDown(rt, tree[rt].r - tree[rt].l + 1);int m = tree[rt].mid();int res = 0;if (r <= m) res += query(l, r, rt << 1);else if (l > m) res += query(l, r, rt << 1 | 1);else{res += query(l, m, rt << 1);res += query(m + 1, r, rt << 1 | 1);}return res;}int main(){int n, m,t,k,a,b;scanf("%d", &t);while (t--){scanf("%d %d", &n, &m);build(1, n, 1);//坐标从1开始while (m--){scanf("%d%d%d", &k, &a, &b);if (k == 2){a++, b++;//变成坐标从1开始的printf("%d\n", query(a, b, 1));update(0, a, b, 1);}int l, r, mid;if (k == 1){a++;//变成坐标从1开始的int sum = query(a, n, 1);if (sum== n - a+1 ){printf("Can not put any one.\n");}else {b = min(b, n - a + 1 - sum);l = a - 1, r = n+1;while (r - l > 1){mid = (l + r) / 2;if ( query(l+1,mid, 1) <mid-l ) r= mid;else l= mid;}int first = r;//坐标从1开始的l = first-1, r = n+1;while (r - l > 1){mid = (l + r) / 2;if (mid-first+1-query(first, mid, 1) >= b) r= mid;else l= mid;}int last = r;//坐标从1开始的printf("%d %d\n", first-1, last-1);update(1, first, last, 1);}}}puts("");}return 0;}


0 0
原创粉丝点击