描述

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

样例输入

  1. 10 6
  2. 3195 2202 4613 3744 2892 4858 619 5079 9478 7366 8942
  3. 0 1 6 886
  4. 1 0 2 9710
  5. 1 0 10 7980
  6. 0 4 9 -7594
  7. 0 2 8 1581
  8. 0 4 4 -1010

样例输出

  1. 58304
  2. 75652
  3. 87780
  4. 42216
  5. 53283
  6. 52273

第一次写这样的,好多细节。现在被搞得有点昏,清晰了再看看。

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. const int maxn=;
  7. using namespace std;
  8. int a[maxn],n;
  9. struct Node
  10. {
  11. int L,R,lazy1,lazy2,sum,cnt;
  12. Node()
  13. {
  14. L=R=lazy1=lazy2=sum=cnt=;
  15. }
  16. };
  17. struct Tree
  18. {
  19. Node node[maxn<<];
  20. void build(int now,int l,int r)
  21. {
  22. node[now].L=l;
  23. node[now].R=r;
  24. node[now].lazy1=node[now].lazy2=;
  25. if(l==r) {
  26. node[now].cnt=;
  27. return ;
  28. }
  29. int Mid=(l+r)>>;
  30. build(now<<,l,Mid);
  31. build(now<<|,Mid+,r);
  32. node[now].cnt=node[now<<].cnt+node[now<<|].cnt;
  33. }
  34. void update(int now)
  35. {
  36. node[now].sum=node[now<<].sum+node[now<<|].sum;
  37. }
  38. void pushdown(int now)
  39. {
  40. if(node[now].lazy1){
  41. node[now<<].lazy1=node[now].lazy1;
  42. node[now<<|].lazy1=node[now].lazy1;
  43. node[now<<].lazy2=;
  44. node[now<<|].lazy2=;
  45. node[now<<].sum=node[now].lazy1*node[now<<].cnt;
  46. node[now<<|].sum=node[now].lazy1*node[now<<|].cnt;
  47. node[now].lazy1=;
  48. }
  49. if(node[now].lazy2)
  50. {
  51. node[now<<].lazy2+=node[now].lazy2;
  52. node[now<<|].lazy2+=node[now].lazy2;
  53. node[now<<].sum+=node[now].lazy2*node[now<<].cnt;
  54. node[now<<|].sum+=node[now].lazy2*node[now<<|].cnt;
  55. node[now].lazy2=;
  56. }
  57.  
  58. }
  59. void insert(int now,int pos,int val)
  60. {
  61. if(node[now].L==node[now].R) {
  62. node[now].sum=val;
  63. return ;
  64. }
  65. int Mid=(node[now].L+node[now].R)>>;
  66. if(pos<=Mid) insert(now<<,pos,val);
  67. else insert(now<<|,pos,val);
  68. update(now);
  69. }
  70. void change(int now,int l,int r,int val,int opt)
  71. {
  72. if(node[now].L>=l&&node[now].R<=r) {
  73. if(opt==){
  74. node[now].lazy1=val;
  75. node[now].lazy2=;
  76. node[now].sum=node[now].cnt*val;
  77. }
  78. else {
  79. node[now].lazy2+=val;
  80. node[now].sum+=node[now].cnt*val;
  81. }
  82. return ;
  83. }
  84. pushdown(now);
  85. int Mid=(node[now].L+node[now].R)>>;
  86. if(Mid>=l) change(now<<,l,r,val,opt);
  87. if(Mid<r) change(now<<|,l,r,val,opt);
  88. update(now);
  89. return ;
  90. }
  91. int query(int now,int l,int r)
  92. {
  93. if(node[now].L>=l&&node[now].R<=r) return node[now].sum;
  94. pushdown(now);
  95. int Mid=(node[now].L+node[now].R)>>;
  96. int s=;
  97. if(Mid>=l) s+=query(now<<,l,r);
  98. if(Mid<r) s+=query(now<<|,l,r);
  99. update(now);
  100. return s;
  101. }
  102. };
  103. Tree tree;
  104. int main()
  105. {
  106. int x,l,r,q,i,opt;
  107. scanf("%d%d",&n,&q);
  108. n++;
  109. tree.build(,,n);
  110. for(i=;i<=n;i++) {
  111. scanf("%d",&a[i]);
  112. tree.insert(,i,a[i]);
  113. }
  114. while(q--){
  115. scanf("%d%d%d%d",&opt,&l,&r,&x);
  116. l++;r++;
  117. tree.change(,l,r,x,opt);
  118. printf("%d\n",tree.query(,,n));
  119. }
  120. return ;
  121. }

HihoCoder1080 更为复杂的买卖房屋姿势(线段树+多重lazy)的更多相关文章

  1. hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新

    #1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...

  2. hiho#1080 更为复杂的买卖房屋姿势 线段树+区间更新

    #1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...

  3. hihoCoder #1080 : 更为复杂的买卖房屋姿势 (线段树,多tag)

    题意: 有编号为0~n的n+1个房屋,给出每个房屋的起始价格,随后给出m种修改,每次修改都要进行输出所有房屋的价格总和.修改有两种方式:(1)政府调控,编号L~R全置为同一价格(0)房屋自行涨跌,编号 ...

  4. hihocoder1080 更为复杂的买卖房屋姿势

    思路: 线段树区间修改,需要使用两个懒标记set和add.处理好两个标记的优先级即可(set之前的set和add是没有作用的). 实现: #include <bits/stdc++.h> ...

  5. hiho1080 更为复杂的买卖房屋姿势

    题目链接: hihocoder1080 题解思路: 题目中对区间改动有两个操作: 0   区间全部点添加v 1   区间全部点改为v easy想到应该使用到两个懒惰标记  一个记录替换  一个记录增减 ...

  6. POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)

    题目链接:http://poj.org/problem?id=3237 一棵有边权的树,有3种操作. 树链剖分+线段树lazy标记.lazy为0表示没更新区间或者区间更新了2的倍数次,1表示为更新,每 ...

  7. 线段树初步&&lazy标记

    线段树 一.概述: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a, ...

  8. 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 ...

  9. 线段树入门&lazy思想

    线段树将区间分成若干个子区间,子区间又继续分,直到区间为一个点(区间左值等于右值) 对于父区间[a,b],其子区间为[a,(a+b)/2]和[(a+b)/2+1,b] 用于求区间的值,如区间最值.区间 ...

随机推荐

  1. 常用模块之hashlib,configparser,logging模块

    常用模块二 hashlib模块 hashlib提供了常见的摘要算法,如md5和sha1等等. 那么什么是摘要算法呢?摘要算法又称为哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定 ...

  2. Dancing Link专题

    一些链接: http://www.cnblogs.com/-sunshine/p/3358922.html http://www.cnblogs.com/grenet/p/3145800.html 1 ...

  3. Js onload 解析

    Js onload的使用方法. 1.在script中调用 window.onload = function(){ function1(); function2(); function3(); }; 或 ...

  4. pyhton3 sys模块

    Python常用模块之sys sys模块提供了一系列有关Python运行环境的变量和函数. 1 ). sys.stdin 标准输入流.2 ).sys.stdout 标准输出流.3 ). sys.std ...

  5. 预防SQL注入攻击

    /** * 预防SQL注入攻击 * @param string $value * @return string */ function check_input($value) { // 去除斜杠 if ...

  6. C++友元概念

    采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口. 但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类 ...

  7. Linux Shell基础 Bash常见命令 echo命令

    概述 shell中常见的命令echo. 输出命令:echo echo命令的输出内容如果没有特殊含义,则将原内容输出到屏幕:如果输出内容有特殊含义,则输出打印其含义. 命令格式如下: [root@loc ...

  8. 【leetcode刷题笔记】Sudoku Solver

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  9. 【Flask】Sqlalchemy join

    ### join:1. join分为left join(左外连接)和right join(右外连接)以及内连接(等值连接).2. 参考的网页:http://www.jb51.net/article/1 ...

  10. 一览Swift中的常用关键字

    要学习Swift这门语言,就必须先了解Swift的关键字及对应的解释.这里就列一下在Swift中常用到的关键字. 关键字是类似于标识符的保留字符序列,除非用重音符号(`)将其括起来,否则不能用作标识符 ...