hiho一下 第二十二周 (线段树上存在冲突的区间修改操作)
来源:互联网 发布:mac结束进程快捷键 编辑:程序博客网 时间:2024/06/05 21:07
题目1 : 更为复杂的买卖房屋姿势
- 样例输入
10 63195 2202 4613 3744 2892 4858 619 5079 9478 7366 8942 0 1 6 8861 0 2 97101 0 10 79800 4 9 -75940 2 8 15810 4 4 -1010
- 样例输出
5830475652877804221653283
52273
说明:题目中有两种修改操作——并且都是区间修改,也就是说如果使用懒惰标记来维护修改的话,关键在于处理好这两种操作之间的冲突。
代码:
#include <iostream>#include <cstdio>using namespace std;const int MAXN = 100005;int N, M;int segTree[MAXN*3];int lazySet[MAXN*3];int lazyAdd[MAXN*3];void pushUp(int node){ segTree[node] = segTree[2*node] + segTree[2*node+1];}void pushDown(int node, int begin, int end){ int m = (begin+end)/2; if(lazySet[node]){ lazyAdd[2*node] = lazyAdd[2*node+1] = 0; //最关键的在此 lazySet[2*node] = lazySet[2*node+1] = lazySet[node]; segTree[2*node] = (m-begin+1)*lazySet[node]; segTree[2*node+1] = (end-m)*lazySet[node]; lazySet[node] = 0; } if(lazyAdd[node]){ lazyAdd[2*node] += lazyAdd[node]; lazyAdd[2*node+1] += lazyAdd[node]; segTree[2*node] += (m-begin+1)*lazyAdd[node]; segTree[2*node+1] += (end-m)*lazyAdd[node]; lazyAdd[node] = 0; }}void build(int node, int begin, int end){ lazySet[node] = lazyAdd[node] = 0; if(begin == end) scanf("%d", &segTree[node]); else{ int m = (begin+end)/2; build(2*node, begin, m); build(2*node+1, m+1, end); pushUp(node); }}void updateAdd(int node, int begin, int end, int a, int b, int c){ if(begin==a && end==b){ lazyAdd[node] += c; segTree[node] += (b-a+1)*c; }else{ pushDown(node, begin, end); int m = (begin+end)/2; if(b<=m) updateAdd(2*node, begin, m, a, b, c); else if(m<a) updateAdd(2*node+1, m+1, end, a, b, c); else{ updateAdd(2*node, begin, m, a, m, c); updateAdd(2*node+1, m+1, end, m+1, b, c); } pushUp(node); }}void updateSet(int node, int begin, int end, int a, int b, int c){ if(begin==a && end==b){ lazySet[node] = c; lazyAdd[node] = 0; segTree[node] = (b-a+1)*c; }else{ pushDown(node, begin, end); int m = (begin+end)/2; if(b<=m) updateSet(2*node, begin, m, a, b, c); else if(a>m) updateSet(2*node+1, m+1, end, a, b, c); else{ updateSet(2*node, begin, m, a, m, c); updateSet(2*node+1, m+1, end, m+1, b, c); } pushUp(node); }}int main(){ int type, a, b, c; scanf("%d %d", &N, &M); build(1, 1, N+1); while(M--){ scanf("%d %d %d %d", &type, &a, &b, &c); a++; b++; if(type == 0){ //房屋自发的涨价或者降价 updateAdd(1, 1, N+1, a, b, c); }else{ //政府有关部门针对房价的硬性调控 updateSet(1, 1, N+1, a, b, c); } printf("%d\n", segTree[1]); } return 0;}
代码二(更简洁和高效一点,其实二者效率差不太多)
#include <iostream>#include <cstdio>using namespace std;const int MAXN = 100005;int N, M;int segTree[MAXN*3];int lazySet[MAXN*3];int lazyAdd[MAXN*3];void pushUp(int node){ segTree[node] = segTree[node<<1] + segTree[node<<1|1];}void pushDown(int node, int begin, int end){ int m = (begin+end)>>1; if(lazySet[node]){ lazyAdd[node<<1] = lazyAdd[node<<1|1] = 0; lazySet[node<<1] = lazySet[node<<1|1] = lazySet[node]; segTree[node<<1] = (m-begin+1)*lazySet[node]; segTree[node<<1|1] = (end-m)*lazySet[node]; lazySet[node] = 0; } if(lazyAdd[node]){ lazyAdd[node<<1] += lazyAdd[node]; lazyAdd[node<<1|1] += lazyAdd[node]; segTree[node<<1] += (m-begin+1)*lazyAdd[node]; segTree[node<<1|1] += (end-m)*lazyAdd[node]; lazyAdd[node] = 0; }}void build(int node, int begin, int end){ lazySet[node] = lazyAdd[node] = 0; if(begin == end){ scanf("%d", &segTree[node]); return; } int m = (begin+end)>>1; build(node<<1, begin, m); build(node<<1|1, m+1, end); pushUp(node);}void updateAdd(int node, int begin, int end, int a, int b, int c){ if(a<=begin && end<=b){ lazyAdd[node] += c; segTree[node] += (end-begin+1)*c; return; } pushDown(node, begin, end); int m = (end+begin)>>1; if(a<=m) updateAdd(node<<1, begin, m, a, b, c); if(m<b) updateAdd(node<<1|1, m+1, end, a, b, c); pushUp(node);}void updateSet(int node, int begin, int end, int a, int b, int c){ if(a<=begin && end<=b){ lazySet[node] = c; lazyAdd[node] = 0; segTree[node] = (end-begin+1)*c; return; } pushDown(node, begin, end); int m = (begin+end)>>1; if(a<=m) updateSet(node<<1, begin, m, a, b, c); if(m<b) updateSet(node<<1|1, m+1, end, a, b, c); pushUp(node);}int main(){ int type, a, b, c; scanf("%d %d", &N, &M); build(1, 1, N+1); while(M--){ scanf("%d %d %d %d", &type, &a, &b, &c); a++; b++; if(type == 0){ //房屋自发的涨价或者降价 updateAdd(1, 1, N+1, a, b, c); }else{ //政府有关部门针对房价的硬性调控 updateSet(1, 1, N+1, a, b, c); } printf("%d\n", segTree[1]); } return 0;}
描述
小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们可以化身上帝模式,买卖房产。
在这个游戏里,会不断的发生如下两种事件:一种是房屋自发的涨价或者降价,而另一种是政府有关部门针对房价的硬性调控。房价的变化自然影响到小Hi和小Ho的决策,所以他们希望能够知道任意时刻某个街道中所有房屋的房价总和是多少——但是很不幸的,游戏本身并不提供这样的计算。不过这难不倒小Hi和小Ho,他们将这个问题抽象了一下,成为了这样的问题:
小Hi和小Ho所关注的街道的长度为N米,从一端开始每隔1米就有一栋房屋,依次编号为0..N,在游戏的最开始,每栋房屋都有一个初始价格,其中编号为i的房屋的初始价格为p_i,之后共计发生了M次事件,所有的事件都是对于编号连续的一些房屋发生的,其中第i次事件如果是房屋自发的涨价或者降价,则被描述为三元组(L_i, R_i, D_i),表示编号在[L_i, R_i]范围内的房屋的价格的增量(即正数为涨价,负数为降价)为D_i;如果是政府有关部门针对房价的硬性调控,则被描述为三元组(L_i, R_i, V_i),表示编号在[L_i, R_i]范围内的房屋的价格全部变为V_i。而小Hi和小Ho希望知道的是——每次事件发生之后,这个街道中所有房屋的房价总和是多少。
提示:这是练习向的一周~
输入
每个测试点(输入文件)有且仅有一组测试数据。
每组测试数据的第1行为两个整数N、M,分别表示街道的长度和总共发生的事件数。
每组测试数据的第2行为N+1个整数,其中第i个整数位p_i,表示编号为i的房屋的初始价格。
每组测试数据的第3-M+2行,按照发生的时间顺序,每行描述一个事件,如果该行描述的事件为,“房屋自发的涨价或者降价”,则该行为4个整数0, L_i, R_i, D_i,意义如前文所述;如果该行描述的事件为“政府有关部门针对房价的硬性调控”,则该行为4个整数1, L_i, R_i, V_i,意义如前文所述。
对于100%的数据,满足N<=10^5,1<=p_i, |D_i|, V_i<=10^4,0<=l_i<r_i<=n。<>
对于100%的数据,满足在任意时刻,任何房屋的价格都处于[1, 10^4]内。
输出
对于每组测试数据,输出M行,其中第i行为一个整数Ans_i,表示第i次事件发生之后,这个街道中所有房屋的房价总和。
- hiho一下 第二十二周 (线段树上存在冲突的区间修改操作)
- hiho一下 第二十周 线段树的区间修改
- hiho一下第二十周 #1078 : 线段树的区间修改 【线段树】
- hiho一下 第二十周(线段树区间修改+延迟标记)
- HIHO #1078 : 线段树的区间修改
- BZOJ-4034: [HAOI2015]树上操作 (树链剖分 入门题 子树整体修改 线段树 区间修改+查询)
- 【区间问题】 hiho一下第152周
- hiho 20 使用线段树进行区间修改
- 【树链剖分+树状数组区间修改区间和】BZOJ4034(LOJ#2125)[HAOI2015]树上操作
- bzoj 4034: [HAOI2015]树上操作(树链剖分+线段树区间更新)
- hiho一下 更为复杂的买卖房屋姿势(线段树)
- hiho一下第二十一周 #1079 : 离散化 【线段树储存区间状态】
- hdu5493(线段树,离线操作,点修改,区间查询)
- Codeforces483D 线段树上的位操作
- Codeforces483D 线段树上的位操作
- Codeforces483D 线段树上的位操作
- (hiho一下 第十九周)线段树之查询空间最小值
- hiho一下 第十九周 RMQ问题再临-线段树
- wamp5 PHP加载curl.dll的方法
- scanf/getchar/gets/cin区别
- Opencv学习笔记(五)Harris角点检测
- C#视频总结(面向对象基础)上
- Spring Web 中模块化配置文件的加载
- hiho一下 第二十二周 (线段树上存在冲突的区间修改操作)
- Apache下error.log文件太大的处理
- Android入门第八篇之GridView(九宫图)
- iOS7 视图切换效果
- Mac OS X10.10_xcode6.1_ios8.1环境下,编译lame静态库libmp3lame.a,支持arm64 armv7s x86_64 i386 armv7指令集
- 软工文档总结
- Wamp 报403 You don't have permission to access
- 嵌入式jetty启动spring(java配置方式),junit测试用
- LayoutInflater中的inflate方法