【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 }
基本代码就是如此,本题没有什么太大的技巧,就不加多说了。
浙公网安备 33010602011771号