#1080 : 更为复杂的买卖房屋姿势

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小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次事件发生之后,这个街道中所有房屋的房价总和。

样例输入
10 6
3195 2202 4613 3744 2892 4858 619 5079 9478 7366 8942
0 1 6 886
1 0 2 9710
1 0 10 7980
0 4 9 -7594
0 2 8 1581
0 4 4 -1010
样例输出
58304
75652
87780
42216
53283
52273题目连接:http://hihocoder.com/problemset/problem/1080

题意:0,l,r,d表示l~r房屋价格涨价d;1,l,r,v表示l~r房屋价格变成v。求每次操作后所有房屋的价格总和。

思路:线段树区间更新。这题有2个lazy,房屋的价格变为set,房屋价格浮动设为add。一个区间上set与add的先后关系——如果对于一个区间set和add标记同时存在,那么应该如果处理:一种情况set在add之前,那么就按照正常顺序来就可以了;另一种情况add在set之前,那么这个add操作就取消,直接set操作就可以了。所以更新线段树的一个区间的时候,如果是set操作,那么就把add的标记清理掉;如果是add操作,那么就正常进行。这样的话就保证两个标记同时出现的时候是先set再add的,这样的话就不会出错。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=1e6+100;
int set[MAXN],add[MAXN];
long long tree[MAXN];
void pushup(int pos)
{tree[pos]=tree[pos<<1]+tree[pos<<1|1];
}
void pushdown(int l,int r,int pos)
{int mid=(l+r)>>1;if(set[pos]){set[pos<<1]=set[pos<<1|1]=set[pos];add[pos<<1]=add[pos<<1|1]=0;tree[pos<<1]=(mid-l+1)*set[pos];tree[pos<<1|1]=(r-(mid+1)+1)*set[pos];set[pos]=0;}if(add[pos]){add[pos<<1]+=add[pos];add[pos<<1|1]+=add[pos];tree[pos<<1]+=(mid-l+1)*add[pos];tree[pos<<1|1]+=(r-(mid+1)+1)*add[pos];add[pos]=0;}
}
void build(int l,int r,int pos)
{if(l==r){scanf("%lld",&tree[pos]);return;}int mid=(l+r)>>1;build(l,mid,pos<<1);build(mid+1,r,pos<<1|1);pushup(pos);
}
void update(int L,int R,int flag,int w,int l,int r,int pos)
{if(L<=l&&r<=R){if(flag==1){set[pos]=w;add[pos]=0;tree[pos]=(r-l+1)*w;}else{add[pos]+=w;tree[pos]+=(r-l+1)*w;}return;}pushdown(l,r,pos);int mid=(l+r)>>1;if(L<=mid) update(L,R,flag,w,l,mid,pos<<1);if(R>mid) update(L,R,flag,w,mid+1,r,pos<<1|1);pushup(pos);
}
int main()
{int n,m;scanf("%d%d",&n,&m);build(1,n+1,1);while(m--){int flag,l,r,w;scanf("%d%d%d%d",&flag,&l,&r,&w);update(l+1,r+1,flag,w,1,n+1,1);printf("%lld\n",tree[1]);}return 0;
}

View Code

转载于:https://www.cnblogs.com/GeekZRF/p/5974897.html

hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新相关推荐

  1. 1080 线段树练习

    1080 线段树练习 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 一行N个方格,开始每个格子里都有一个整数.现在动态地提出 ...

  2. P3899 [湖南集训]更为厉害(线段树合并、长链剖分、二维数点)

    P3899 [湖南集训]更为厉害 若 deepb<deepa\text{deep}_b<\text{deep}_adeepb​<deepa​:c 在点 a 的子树中,根据乘法原理计算 ...

  3. hihocoder #1078 : 线段树的区间修改

    解题思路:基础的线段树区间修改 我按照书上敲的代码不知道为什么WA... #include<iostream> #include<cstdio> #include<cst ...

  4. hihoCoder 1116 计算 (线段树)

    题意 : 描述 现在有一个有n个元素的数组a1, a2, ..., an. 记f(i, j) = ai * ai+1 * ... * aj. 初始时,a1 = a2 = ... = an = 0,每次 ...

  5. 【HihoCoder - 1831】80 Days(尺取 或 线段树)

    题干: 80 Days is an interesting game based on Jules Verne's science fiction "Around the World in ...

  6. DFS序+线段树 hihoCoder 1381 Little Y's Tree(树的连通块的直径和)

    题目链接 #1381 : Little Y's Tree 时间限制:24000ms 单点时限:4000ms 内存限制:512MB 描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每 ...

  7. 我的hihocoder存代码

    hihocoder的教程挺好理解,这里存代码. 1014 Trie树 #include <cstdio> #include <cmath> #include <cstri ...

  8. 线段树开新坑:kuangbin带你飞

    写在最前面的废话 这里I以前的题是暑假刚刚开始的时候在家写的,然后多校一波就荒废了 9月开头回家一波,重新填坑,= =,kuangbin带你飞的pdf,这才一半题,后面还有一波,蓝瘦,慢慢写吧,不写题 ...

  9. Hihocoder 1077

    Hihocoder 1077 题意 ​ 中文题. 解题思路 ​ 线段树裸题. 代码 #include<bits/stdc++.h> using namespace std; const i ...

最新文章

  1. 【电路】pmic芯片设计细节
  2. 绩效面谈流程,阿里是这样做的
  3. 第四周课程总结及实验报告
  4. showModalDialog和showModelessDialog缓存问题,参数详解,
  5. AspectJ基于xml和基于注解
  6. 前端学习(1393):多人管理项目13加密实现
  7. python爬虫短片_Python爬虫练习:爬取全民小视频(附代码,过程)
  8. Linux CPU占用率监控工具小结
  9. 第二次冲刺个人博客02
  10. 程序functionLua基础 小结(两个Lua程序示例)
  11. python取文件后缀
  12. (转载)Stackoverflow让我们变懒了?
  13. jQuery - animate(滑块滑动)
  14. Samba 共享服务
  15. React源码分析 - 组件初次渲染
  16. 今日头条推荐算法原理全文详解之五
  17. Linux下限制带宽的方法
  18. OpenHarmony恢复启动子系统init进程之服务管理与发布
  19. 【knex】 knex.js中 orderBy多个字段排序
  20. PGP加密技术应用(含安装包)

热门文章

  1. c++interesting转换为uint_能让手机电脑“小屏变大屏”的神奇转换器,到底是个什么玩意儿?...
  2. EasyUI Easyloader 加载器
  3. Windows cmd终端美化:Windows terminal背景图
  4. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)(热身赛)
  5. 分段式多级离心泵_溧阳耐磨矿用多级泵水泵厂
  6. Spring→事务、隔离级别、事务传播行为、编程式事务控制、XML配置声明式事务(原始方式)、XML配置声明式事务(基于tx/aop)、@注解配置声明式事务、优势总结
  7. java 获取 t 的类型_如何获取类型为T的字段的类?
  8. gcd常见结论及gcd与斐波那契结合--hdu6363.
  9. python ui自动_pytest+python下的UI自动化基础框架
  10. 计算机组成原理—Cache和主存的映射模式