POJ 3468(线段树)

线段树区间更新和区间查询模板题,加懒标记防止其时间复杂度退化

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 using namespace std;
  6 #define ls (pos<<1)
  7 #define rs (pos<<1|1)
  8 const int MAXN=100000+10;
  9 struct node
 10 {
 11      int l,r,add;
 12      long long sum;
 13      int mid()
 14      {
 15           return (l+r)>>1;
 16      }
 17 };
 18 node tree[MAXN<<2];
 19 int a[MAXN];
 20 void maintain(int pos)
 21 {
 22      tree[pos].sum=tree[ls].sum+tree[rs].sum;
 23 }
 24 void build(int l,int r,int pos)
 25 {
 26      tree[pos].l=l;
 27      tree[pos].r=r;
 28      tree[pos].add=0;
 29      if(l==r)
 30      {
 31           tree[pos].sum=(long long)a[l];
 32           return;
 33      }
 34      int mid=tree[pos].mid();
 35      build(l,mid,ls);
 36      build(mid+1,r,rs);
 37      maintain(pos);
 38 }
 39 void pushdown(int pos,int m)
 40 {
 41      if(tree[pos].add)
 42      {
 43           if(tree[pos].l==tree[pos].r)
 44           {
 45                tree[pos].add=0;
 46                return;
 47           }
 48           tree[ls].add+=tree[pos].add;
 49           tree[rs].add+=tree[pos].add;
 50           tree[ls].sum+=(long long)(m-(m>>1))*tree[pos].add;
 51           tree[rs].sum+=(long long)(m>>1)*tree[pos].add;
 52           tree[pos].add=0;
 53      }
 54 }
 55 void update(int l,int r,int c,int pos)
 56 {
 57      if(l<=tree[pos].l&&tree[pos].r<=r)
 58      {
 59           tree[pos].add+=c;
 60           tree[pos].sum+=(long long)(tree[pos].r-tree[pos].l+1)*c;
 61           return;
 62      }
 63      pushdown(pos,(tree[pos].r-tree[pos].l+1));
 64      int mid=tree[pos].mid();
 65      if(r<=mid) update(l,r,c,ls);
 66      else if(l>mid) update(l,r,c,rs);
 67      else
 68      {
 69           update(l,mid,c,ls);
 70           update(mid+1,r,c,rs);
 71      }
 72      maintain(pos);
 73 }
 74 long long query(int l,int r,int pos)
 75 {
 76      if(l<=tree[pos].l&&tree[pos].r<=r)
 77      {
 78           return tree[pos].sum;
 79      }
 80      pushdown(pos,(tree[pos].r-tree[pos].l+1));
 81      int mid=tree[pos].mid();
 82      long long ans=0;
 83      if(r<=mid) ans=query(l,r,ls);
 84      else if(l>mid) ans=query(l,r,rs);
 85      else
 86      {
 87           ans=query(l,mid,ls)+query(mid+1,r,rs);
 88      }
 89      return ans;
 90 }
 91 int main()
 92 {
 93      int n,q;
 94      while(scanf("%d%d",&n,&q)==2)
 95      {
 96           for(int i=1;i<=n;i++)
 97                scanf("%d",&a[i]);
 98           build(1,n,1);
 99           char c;
100           int l,r,k;
101           while(q--)
102           {
103                scanf(" %c",&c);
104                if(c=='Q')
105                {
106                     scanf("%d%d",&l,&r);
107                     long long ans=query(l,r,1);
108                     printf("%lld\n",ans);
109                }
110                else
111                {
112                     scanf("%d%d%d",&l,&r,&k);
113                     update(l,r,k,1);
114                }
115           }
116      }
117      return 0;
posted @ 2018-04-20 14:23  WOOOOO  阅读(172)  评论(0编辑  收藏  举报