码迷,mamicode.com
首页 > 其他好文 > 详细

hihocoder1080线段树+区间修改+区间查询+多个懒标记

时间:2015-02-22 16:54:03      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:

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

对于这种不止一个懒标记的线段树,只要弄清楚各种操作和各种懒标记间的关系就OK了。

我的代码:

  1 #include <cstdio>
  2 
  3 using namespace std;
  4 
  5 #define MAXN 100005
  6 
  7 int p[MAXN];
  8 
  9 struct segNode
 10 {
 11     int left, right, sum, dd, vv;
 12     bool lazy1, lazy2;
 13 };
 14 
 15 struct segTree
 16 {
 17     segNode t[4*MAXN];
 18     void build(int i, int l, int r)
 19     {
 20         t[i].left = l;
 21         t[i].right = r;
 22         t[i].lazy1 = false;
 23         t[i].lazy2 = false;
 24         t[i].dd = 0;
 25         if(l<r)
 26         {
 27             int m = (l+r)/2;
 28             build(2*i, l, m);
 29             build(2*i+1, m+1, r);
 30             t[i].sum = t[2*i].sum+t[2*i+1].sum;
 31         }
 32         else    t[i].sum = p[l];
 33     }
 34     void pushdown(int i)
 35     {
 36         if(t[i].left<t[i].right)
 37         {
 38             if(t[i].lazy2)
 39             {
 40                 t[2*i].vv = t[i].vv;
 41                 t[2*i+1].vv = t[i].vv;
 42                 t[2*i].sum = (t[2*i].right-t[2*i].left+1)*t[i].vv;
 43                 t[2*i+1].sum = (t[2*i+1].right-t[2*i+1].left+1)*t[i].vv;
 44                 t[2*i].dd = 0;
 45                 t[2*i+1].dd = 0;
 46                 t[2*i].lazy1 = false;
 47                 t[2*i+1].lazy1 = false;
 48                 t[2*i].lazy2 = true;
 49                 t[2*i+1].lazy2 = true;
 50             }
 51             else if(t[i].lazy1)
 52             {
 53                 t[2*i].sum += (t[2*i].right-t[2*i].left+1)*t[i].dd;
 54                 t[2*i+1].sum += (t[2*i+1].right-t[2*i+1].left+1)*t[i].dd;
 55                 if(t[2*i].lazy2)    t[2*i].vv += t[i].dd;
 56                 else
 57                 {
 58                     t[2*i].dd += t[i].dd;
 59                     t[2*i].lazy1 = true;
 60                 }
 61                 if(t[2*i+1].lazy2)  t[2*i+1].vv += t[i].dd;
 62                 else
 63                 {
 64                     t[2*i+1].dd += t[i].dd;
 65                     t[2*i+1].lazy1 = true;
 66                 }
 67             }
 68         }
 69         t[i].dd = 0;
 70         t[i].lazy1 = false;
 71         t[i].lazy2 = false;
 72     }
 73     void update(int i, int op, int l, int r, int v)
 74     {
 75         pushdown(i);
 76         if(t[i].left==l&&t[i].right==r)
 77         {
 78             if(op)
 79             {
 80                 t[i].vv = v;
 81                 t[i].dd = 0;
 82                 t[i].sum = (t[i].right-t[i].left+1)*v;
 83                 t[i].lazy2 = true;
 84             }
 85             else
 86             {
 87                 t[i].dd = v;
 88                 t[i].sum += (t[i].right-t[i].left+1)*v;
 89                 t[i].lazy1 = true;
 90             }
 91         }
 92         else
 93         {
 94             int m = (t[i].left+t[i].right)/2;
 95             if(r<=m) update(2*i, op, l, r, v);
 96             else if(l>m) update(2*i+1, op, l, r, v);
 97             else
 98             {
 99                 update(2*i, op, l, m, v);
100                 update(2*i+1, op, m+1, r, v);
101             }
102             t[i].sum = t[2*i].sum+t[2*i+1].sum;
103         }
104     }
105     int query(int i, int l, int r)
106     {
107         pushdown(i);
108         if(t[i].left==l&&t[i].right==r) return t[i].sum;
109         int m = (t[i].left+t[i].right)/2;
110         if(r<=m)    return query(2*i, l, r);
111         if(l>m) return query(2*i+1, l, r);
112         return query(2*i, l, m)+query(2*i+1, m+1, r);
113     }
114 }tree;
115 
116 int main()
117 {
118     int n, m;
119     while(scanf("%d%d", &n, &m)!=EOF)
120     {
121         for(int i=0; i<=n; ++i) scanf("%d", &p[i]);
122         tree.build(1, 0, n);
123         while(m--)
124         {
125             int op, l, r, v;
126             scanf("%d%d%d%d", &op, &l, &r, &v);
127             tree.update(1, op, l, r, v);
128             printf("%d\n", tree.query(1, 0, n));
129         }
130     }
131     return 0;
132 }

 

hihocoder1080线段树+区间修改+区间查询+多个懒标记

标签:

原文地址:http://www.cnblogs.com/pczhou/p/4297560.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!