poj 3468 A Simple Problem with Integers(線段樹#6 / 樹狀數組)

線段樹,維護一個add域和lazy

2672ms

也可以用樹狀數組來做:http://kenby.iteye.com/blog/962159

這裏給出線段樹代碼


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring> 
using namespace std;
#define N 100005 
typedef long long ll;
 

struct node{
       int l, r;
       ll sum;
       ll add; 
       bool lazy; 
}Tree[N * 5];
int a[N];
 

 
 

ll build(int l, int r, int x)
{
     Tree[x].l = l;
     Tree[x].r = r;
     Tree[x].add = 0;
     Tree[x].lazy = 0; 
     if (l  ==  r)
     {
            Tree[x].sum = a[Tree[x].l]; 
            return Tree[x].sum;
     } 
     int mid = (l + r) / 2;
     Tree[x].sum = build(l, mid, x * 2) + build(mid + 1, r, x * 2 + 1);
     return Tree[x].sum; 
} 

void push_down(int x)
{
      Tree[x * 2].add += Tree[x].add;
      Tree[x * 2 + 1].add += Tree[x].add;
      Tree[x].sum += Tree[x].add * (Tree[x].r - Tree[x].l + 1); 
      Tree[x].lazy = 0;
      Tree[x].add = 0; 
      Tree[x * 2].lazy = 1;
      Tree[x * 2 + 1].lazy = 1;
}

void update(int l, int r, int val, int x)
{
     if ((Tree[x].l == l && Tree[x].r == r))
     {
               Tree[x].lazy = 1;
               Tree[x].add += val; 
               return ;
     }
     if (Tree[x].lazy == 1)
               push_down(x);
     int mid = (Tree[x].l + Tree[x].r) / 2;
     if (mid < l)update(l, r, val, x * 2 + 1);
     else if (mid >= r)update(l, r, val, x * 2);
     else {
            update(l, mid, val, x * 2);
            update(mid + 1, r, val, x * 2 + 1);
     }
     Tree[x].sum += (val * (r - l + 1));
}  

ll find(int l, int r, int x)
{
       if (l == Tree[x].l && r == Tree[x].r )
       {
               return (r - l + 1) * Tree[x].add  + Tree[x].sum;
       }
       ll ans = 0; 
       if (Tree[x].lazy)
       {
                        ans += (Tree[x].add) * ( r - l + 1);
       } 
       int mid = (Tree[x].l + Tree[x].r) / 2;
       if (mid < l) ans += find(l, r, x * 2 + 1);
       else if (mid >= r) ans +=  find(l, r, x * 2);
       else {
            ans += (find(l, mid,  x * 2) + find(mid + 1, r,  x * 2 + 1)) ; 
       }
       return ans; 
}                         
      
int main()
{
      int n, q;
    //  FILE* fp = fopen("in.txt", "r");
     // FILE* ff = fopen("out.txt", "w"); 
      scanf("%d %d", &n, &q);
      for (int i = 1; i <= n; i++)
             scanf( "%d", a + i);
      build(1, n, 1);
      char op[3];
      int a, b, c; 
      for (int i = 0; i < q; i++)
      {
            scanf( "%s %d %d", op, &a, &b);
            if (op[0] == 'C')
            {
                      scanf(  "%d", &c);
                      update(a, b, c, 1);
            }
            else 
            {
                  
                //fprintf(ff, "%intd\n", find(a, b, 1));
                printf( "%lld\n", find(a, b, 1));
            } 
      } 
      // getchar();          
      
      return 0;
} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章