HihoCoder1080 更为复杂的买卖房屋姿势(线段树+多重lazy)
描述
小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
第一次写这样的,好多细节。现在被搞得有点昏,清晰了再看看。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
const int maxn=;
using namespace std;
int a[maxn],n;
struct Node
{
int L,R,lazy1,lazy2,sum,cnt;
Node()
{
L=R=lazy1=lazy2=sum=cnt=;
}
};
struct Tree
{
Node node[maxn<<];
void build(int now,int l,int r)
{
node[now].L=l;
node[now].R=r;
node[now].lazy1=node[now].lazy2=;
if(l==r) {
node[now].cnt=;
return ;
}
int Mid=(l+r)>>;
build(now<<,l,Mid);
build(now<<|,Mid+,r);
node[now].cnt=node[now<<].cnt+node[now<<|].cnt;
}
void update(int now)
{
node[now].sum=node[now<<].sum+node[now<<|].sum;
}
void pushdown(int now)
{
if(node[now].lazy1){
node[now<<].lazy1=node[now].lazy1;
node[now<<|].lazy1=node[now].lazy1;
node[now<<].lazy2=;
node[now<<|].lazy2=;
node[now<<].sum=node[now].lazy1*node[now<<].cnt;
node[now<<|].sum=node[now].lazy1*node[now<<|].cnt;
node[now].lazy1=;
}
if(node[now].lazy2)
{
node[now<<].lazy2+=node[now].lazy2;
node[now<<|].lazy2+=node[now].lazy2;
node[now<<].sum+=node[now].lazy2*node[now<<].cnt;
node[now<<|].sum+=node[now].lazy2*node[now<<|].cnt;
node[now].lazy2=;
} }
void insert(int now,int pos,int val)
{
if(node[now].L==node[now].R) {
node[now].sum=val;
return ;
}
int Mid=(node[now].L+node[now].R)>>;
if(pos<=Mid) insert(now<<,pos,val);
else insert(now<<|,pos,val);
update(now);
}
void change(int now,int l,int r,int val,int opt)
{
if(node[now].L>=l&&node[now].R<=r) {
if(opt==){
node[now].lazy1=val;
node[now].lazy2=;
node[now].sum=node[now].cnt*val;
}
else {
node[now].lazy2+=val;
node[now].sum+=node[now].cnt*val;
}
return ;
}
pushdown(now);
int Mid=(node[now].L+node[now].R)>>;
if(Mid>=l) change(now<<,l,r,val,opt);
if(Mid<r) change(now<<|,l,r,val,opt);
update(now);
return ;
}
int query(int now,int l,int r)
{
if(node[now].L>=l&&node[now].R<=r) return node[now].sum;
pushdown(now);
int Mid=(node[now].L+node[now].R)>>;
int s=;
if(Mid>=l) s+=query(now<<,l,r);
if(Mid<r) s+=query(now<<|,l,r);
update(now);
return s;
}
};
Tree tree;
int main()
{
int x,l,r,q,i,opt;
scanf("%d%d",&n,&q);
n++;
tree.build(,,n);
for(i=;i<=n;i++) {
scanf("%d",&a[i]);
tree.insert(,i,a[i]);
}
while(q--){
scanf("%d%d%d%d",&opt,&l,&r,&x);
l++;r++;
tree.change(,l,r,x,opt);
printf("%d\n",tree.query(,,n));
}
return ;
}
HihoCoder1080 更为复杂的买卖房屋姿势(线段树+多重lazy)的更多相关文章
- hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新
#1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...
- hiho#1080 更为复杂的买卖房屋姿势 线段树+区间更新
#1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...
- hihoCoder #1080 : 更为复杂的买卖房屋姿势 (线段树,多tag)
题意: 有编号为0~n的n+1个房屋,给出每个房屋的起始价格,随后给出m种修改,每次修改都要进行输出所有房屋的价格总和.修改有两种方式:(1)政府调控,编号L~R全置为同一价格(0)房屋自行涨跌,编号 ...
- hihocoder1080 更为复杂的买卖房屋姿势
思路: 线段树区间修改,需要使用两个懒标记set和add.处理好两个标记的优先级即可(set之前的set和add是没有作用的). 实现: #include <bits/stdc++.h> ...
- hiho1080 更为复杂的买卖房屋姿势
题目链接: hihocoder1080 题解思路: 题目中对区间改动有两个操作: 0 区间全部点添加v 1 区间全部点改为v easy想到应该使用到两个懒惰标记 一个记录替换 一个记录增减 ...
- POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)
题目链接:http://poj.org/problem?id=3237 一棵有边权的树,有3种操作. 树链剖分+线段树lazy标记.lazy为0表示没更新区间或者区间更新了2的倍数次,1表示为更新,每 ...
- 线段树初步&&lazy标记
线段树 一.概述: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a, ...
- Codeforces 834D The Bakery【dp+线段树维护+lazy】
D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...
- 线段树入门&lazy思想
线段树将区间分成若干个子区间,子区间又继续分,直到区间为一个点(区间左值等于右值) 对于父区间[a,b],其子区间为[a,(a+b)/2]和[(a+b)/2+1,b] 用于求区间的值,如区间最值.区间 ...
随机推荐
- 在运行myeclipse10注册机时,显示找不到com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel这个包
在win7下安装MyEclipse10.安装完成之后运行注册机,总是提示classnotfond显示找不到com.sun.java.swing.plaf.nimbus.NimbusLookAndFee ...
- css字体样式
css字体样式(Font Style) 属性 css文本样式 序号 中文说明 标记语法 1 字体样式 {font:font-style font-variant font-weight f ...
- 美图秀秀 web开发图片编辑器
美图秀秀web开发平台 http://open.web.meitu.com/wiki/ 1.环境配置 1.1.设置crossdomain.xml 下载crossdomain.xml文件,把解压出来的c ...
- JQuery 评分系统
评分: ☆ ☆ ☆ ☆ ☆ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ...
- Python学习进程(6)函数
函数最重要的目的是方便我们重复使用相同的一段程序. (1)函数的定义: 函数定义的简单规则: 1.函数代码块以 def 关键词开头,后接函数标识符名称和圆括号(): 2.任何传入参数和 ...
- Redis集群环境搭建
Redis集群cluster环境搭建 描述:本章节主要单服务器搭建集群,在一个服务器上启动多个不同端口的redis服务,非真实环境. 真实环境下redis集群会搭建在多个物理服务器上,并非单一的服务器 ...
- 【TECH】CAS php客户端配置
搞完java又搞php,我整个人都不好了=.= 跟大师在linux上折腾了一下午,没调出来,早上在windows上跑通了,中午终于在linux上搞定了,嘿嘿. server端配置参见这里 在windo ...
- java利用反射将pojo转为json对象
最近做以太坊钱包项目需要与前台进行json交互,写一个工具类,经普通javaBean转为json对象 package util; import java.lang.reflect.Field; imp ...
- IDEA: 遇到问题Error during artifact deployment. See server log for details.详解
IDEA 的配置确实有些烦人,完整的配置我之前发过,现在有个著名的报错: Error during artifact deployment. See server log for details. 这 ...
- SEM竞价数据基本分析方法
今天我们从账户数据表现来看一看怎样通过数据分析,判断账户出现的问题及解决思路.也欢迎大家提出意见,共同讨论进步. 首先我们从关键词报告来分析数据: 以上图数据为例.(设定该行业CPC均价为8) 先说下 ...