hihocoder1078线段树修改区间查询区间(懒标记)

题目链接:http://hihocoder.com/problemset/problem/1078

我的代码:

  1 #include <iostream>
  2 #include <algorithm>
  3
  4 using namespace std;
  5
  6 #define MAXN 100005
  7
  8 int w[MAXN];
  9
 10 struct segNode
 11 {
 12     int left, right, sum;
 13     bool lazy;
 14 };
 15
 16 struct segTree
 17 {
 18     segNode t[4*MAXN];
 19     void build(int i, int l, int r)
 20     {
 21         t[i].left = l;
 22         t[i].right = r;
 23         t[i].lazy = false;
 24         if(l<r)
 25         {
 26             int m = (l+r)/2;
 27             build(2*i, l, m);
 28             build(2*i+1, m+1, r);
 29             t[i].sum = t[2*i].sum+t[2*i+1].sum;
 30         }
 31         else t[i].sum = w[l];
 32     }
 33     int query(int i, int l, int r)
 34     {
 35         if(t[i].lazy) pushdown(i);
 36         if(t[i].left==l&&t[i].right==r) return t[i].sum;
 37         int m = (t[i].left+t[i].right)/2;
 38         if(l>m) return query(2*i+1, l, r);
 39         if(r<=m) return query(2*i, l, r);
 40         return query(2*i, l, m)+query(2*i+1, m+1, r);
 41     }
 42     void update(int i, int l, int r, int v)
 43     {
 44         if(t[i].lazy) pushdown(i);
 45         if(t[i].left==l&&t[i].right==r)
 46         {
 47             t[i].sum = (t[i].right-t[i].left+1)*v;
 48             t[i].lazy = true;
 49         }
 50         else
 51         {
 52             int m = (t[i].left+t[i].right)/2;
 53             if(l>m) update(2*i+1, l, r, v);
 54             else if(r<=m) update(2*i, l, r, v);
 55             else
 56             {
 57                 update(2*i, l, m, v);
 58                 update(2*i+1, m+1, r, v);
 59             }
 60             t[i].sum = t[2*i].sum+t[2*i+1].sum;
 61         }
 62     }
 63     void pushdown(int i)
 64     {
 65         t[i].lazy = false;
 66         if(t[i].left<t[i].right)
 67         {
 68             int l = t[i].right-t[i].left+1;
 69             int ll = t[2*i].right-t[2*i].left+1;
 70             int rl = t[2*i+1].right-t[2*i+1].left+1;
 71             t[2*i].sum = t[i].sum/l*ll;
 72             t[2*i+1].sum = t[i].sum/l*rl;
 73             t[2*i].lazy = true;
 74             t[2*i+1].lazy = true;
 75         }
 76     }
 77 }tree;
 78
 79 int main()
 80 {
 81     int n, q;
 82     bool op;
 83     while(cin>>n)
 84     {
 85         for(int i=1; i<=n; ++i) cin>>w[i];
 86         tree.build(1, 1, n);
 87         cin>>q;
 88         while(q--)
 89         {
 90             cin>>op;
 91             if(op)
 92             {
 93                 int l, r, v;
 94                 cin>>l>>r>>v;
 95                 tree.update(1, l, r, v);
 96             }
 97             else
 98             {
 99                 int l, r;
100                 cin>>l>>r;
101                 cout<<tree.query(1, l, r)<<endl;
102             }
103         }
104     }
105     return 0;
106 }
时间: 2024-08-09 19:52:50

hihocoder1078线段树修改区间查询区间(懒标记)的相关文章

HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:给你一个长度n的数列,初始都为0,有三种操作,第一种给第k个位置的数加d,第二种是查询区间 [l , r] 的总和,第三种是使区间 [l , r] 的值改为离它最近的那个斐波那契数的值. 我刚开始用sum数组存储节点的值,第三种操作是个区间更新,但是区间更新的值不一样,我就想当然的搜到最底部的节点来处理更新,果断T了.后来想了想,其实可以在节点上再加一个信息,就是这个值下次进行第三种操作要变

线段树2 求区间最小值

线段树2 求区间最小值 从数组arr[0...n-1]中查找某个数组某个区间内的最小值,其中数组大小固定,但是数组中的元素的值可以随时更新. 数组[2, 5, 1, 4, 9, 3]可以构造如下的二叉树(背景为白色表示叶子节点,非叶子节点的值是其对应数组区间内的最小值,例如根节点表示数组区间arr[0...5]内的最小值是1): 线段树的四种操作: 1.线段树的创建 2.线段树的查询 3.线段树的更新单节点 4.线段树的更新区间 直接上完整代码吧 1 #include <bits/stdc++.

POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 140120   Accepted: 43425 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type o

UVA-1400 Ray, Pass me the Dishes, LA 3938 , 线段树,区间查询

题意:给出一列数(n个),m次查询区间[l,r]的最大连续区间[x,y](l<=x<=y<=r).(n,m<=500 000) 思路:动态查询区间最大连续区间: 如果是求最大连续区间和: 用线段树维护最大连续和sum_sub.最大前缀和sum_prefix.最大后缀和sum_suffix. root.sum_sub = max{l.sum_sub, r.sum_sub, (l.sum_suffix + r.sum_prefix) }; 题目要求区间,类似的: 用线段树维护最大连续区

UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)

题目链接:http://acm.upc.edu.cn/problem.php?id=2224 题意:给出n个数pi,和m个查询,每个查询给出l,r,a,b,让你求在区间l~r之间的pi的个数(A<=pi<=B,l<=i<=r). 参考链接:http://www.cnblogs.com/zj62/p/3558967.html #include <iostream> #include <cstdio> #include <cstring> #incl

hdu - 4973 - A simple simulation problem.(线段树单点更新 + 区间更新)

题意:初始序列 1, 2, ..., n,m次操作(1 <= n,m<= 50000),每次操作可为: D l r,将区间[l, r]中的所有数复制一次: Q l r,输出区间[l, r]中同一数字个数的最大值. (0 <= r – l <= 10^8, 1 <= l, r <= 序列元素个数) 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4973 -->>因为区间内数字是依次递增的,所以可以以数字为叶建线段

【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each

【HDU】1754 I hate it ——线段树 单点更新 区间最值

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 37448    Accepted Submission(s): 14816 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要

hdu 3308 线段树单点更新 区间合并

http://acm.hdu.edu.cn/showproblem.php?pid=3308 学到两点: 1.以区间端点为开始/结束的最长......似乎在Dp也常用这种思想 2.分类的时候,明确标准逐层分类,思维格式: 条件一成立: { 条件二成立: { } else { } } else { 条件二成立: { } else { } } 上面的这种方式很清晰,如果直接想到那种情况iif(条件一 &条件二)就写,很容易出错而且把自己搞乱,或者情况不全,,,我就因为这WA了几次 3.WA了之后 ,