【POJ】 3468 A Simple Problem with Integers

题目链接:http://poj.org/problem?id=3468

成段更新线段树的简单题,因为思路很容易出来,而且基本套用模板就能AC掉… 不说了… = = 这是我写了两天线段树唯一一道1Y的题,坑…

 

#define LL(x)   (x<<1)  
#define RR(x)   x<<1|1    //使用位运算一来方便,二来优化一点点时间(有些情况下能优化不少时间那~)
#define MAXN 10000000
int n, q, a[100005];

struct node
{
    int l, r;
    int add;     //更新标记变量
    long long sum;         //鉴于数据较大  -1000000000 ≤ Ai ≤ 1000000000. 故应该使用long long来求和
}tree[MAXN];

 

 1 void BuildTree(int index, int left, int right)
 2 {
 3     tree[index].l = left;
 4     tree[index].r = right;
 5     tree[index].add = 0;   //相较单点更新,成段更新需要增加标记变量
 6     if(left == right){
 7            tree[index].sum = (long long)a[left];
 8            return ;
 9     }
10     BuildTree(LL(index),left,(left+right)/2);
11     BuildTree(RR(index),(right+left)/2+1,right);
12     tree[index].sum = tree[LL(index)].sum + tree[RR(index)].sum;
13 }

 

 1 void Update(int index, int x, int y, int add)
 2 {
 3     if(tree[index].l != tree[index].r && tree[index].add){  //延迟做法的向下更新操作,很重要!
 4            tree[LL(index)].add += tree[index].add;
 5            tree[LL(index)].sum += ((long long)tree[index].add) *(tree[LL(index)].r-tree[LL(index)].l+1);
 6            tree[RR(index)].add += tree[index].add;
 7            tree[RR(index)].sum += ((long long)tree[index].add) *(tree[RR(index)].r-tree[RR(index)].l+1);
 8            tree[index].add = 0;
 9     }
10     if(tree[index].l==x && tree[index].r==y){
11           tree[index].add += add;
12           tree[index].sum += ((long long)add) *(y-x+1);
13           return;
14     }
15     else if(y<=tree[LL(index)].r) Update(LL(index),x,y,add);
16     else if(x>=tree[RR(index)].l)  Update(RR(index),x,y,add);
17     else{
18           Update(LL(index),x,tree[LL(index)].r,add);
19           Update(RR(index),tree[RR(index)].l,y,add);
20     }
21     tree[index].sum = tree[LL(index)].sum + tree[RR(index)].sum;
22 }

 

 1 long long Query(int index, int x, int y)
 2 {
 3      if(tree[index].l != tree[index].r && tree[index].add){ //查询的时候也需要更新,为什么?根据本题的样例自己推一遍也就明白了~
 4            tree[LL(index)].add += tree[index].add;
 5            tree[LL(index)].sum += ((long long)tree[index].add) *(tree[LL(index)].r-tree[LL(index)].l+1);
 6            tree[RR(index)].add += tree[index].add;
 7            tree[RR(index)].sum += ((long long)tree[index].add) *(tree[RR(index)].r-tree[RR(index)].l+1);
 8            tree[index].add = 0;
 9     }
10     if(tree[index].l==x && tree[index].r==y){
11           return tree[index].sum;
12     }
13     else if(y<=tree[LL(index)].r) return Query(LL(index),x,y);
14     else if(x>=tree[RR(index)].l) return Query(RR(index),x,y);
15     else return  Query(LL(index),x,tree[LL(index)].r)+Query(RR(index),tree[RR(index)].l,y);
16 }

 

基本代码就是如此,本题没有什么太大的技巧,就不加多说了。

posted on 2012-07-30 01:39  Yuna_  阅读(98)  评论(0)    收藏  举报