【HDU】 1698 Just a Hook
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698
题目意思是给出n个sticks,初始他们的价值都是1。接下来有q个操作,是将x~y的sticks的价值改为z(z=1、2、3),问操作结束后n个sticks的总价值。
NotOnlySuccess称之为成段更新问题,而这类问题要用到懒惰标记,merlininice师父最初跟我讲这块的时候将方法和原理全盘托出,所以我在理解这块的时候还是很顺畅的。
懒惰更新的实质就是在处理区间问题的时候,每次都只需要处理到整区间,不需要再更新到叶子节点了。但是如果仅仅只这样处理,肯定是不对的,如果我们后续访问到这个区间的子节点的时候,由于实际之前这段区间的所有值都已经更新了,但是之前的操作中我们没有更新下去,导致这次我们得到的其实是初始值,这样得到的结果肯定是错误的。
于是我们加一个add的标记,当每次调用update更新的时候我们首先判断当前这个节点有没有在之前额操作中被更新过,如果有,我们就更新他的子节点,然后将他的add值置零并且他的子节点的add值做修改(这个很关键)。这样我们其实是在下一次需要这个区间的时候才去更新他,既节约了时间,又保证了正确性。
难怪NotOnlySuccess会写:
题意:O(-1)
思路:O(-1)
还真是如此....
Just a Hook
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <string> 5 #include <cstring> 6 using namespace std; 7 #define LL(x) (x<<1) 8 #define RR(x) (x<<1)+1 9 #define MAXN 10000000 10 11 struct node 12 { 13 int l, r, sum, add; 14 }tree[MAXN]; 15 16 void BuildTree(int index, int left, int right) 17 { 18 tree[index].l = left; 19 tree[index].r = right; 20 if(left == right){ 21 tree[index].sum = 1; 22 tree[index].add = 0; 23 return ; 24 } 25 BuildTree(LL(index),left,(right+left)/2); 26 BuildTree(RR(index),(right+left)/2+1,right); 27 tree[index].sum = tree[LL(index)].sum + tree[RR(index)].sum; 28 tree[index].add = 0; 29 } 30 31 void Update(int index, int x, int y, int val) 32 { 33 if(tree[index].l != tree[index].r && tree[index].add){ //懒惰更新 34 tree[LL(index)].sum = tree[index].add *(tree[LL(index)].r-tree[LL(index)].l+1); 35 tree[LL(index)].add = tree[index].add; 36 tree[RR(index)].sum = tree[index].add *(tree[RR(index)].r-tree[RR(index)].l+1); 37 tree[RR(index)].add = tree[index].add; 38 tree[index].add = 0; 39 } 40 if(tree[index].l==x && tree[index].r==y){ 41 tree[index].sum = (y-x+1)*val; 42 tree[index].add = val; 43 return ; 44 } 45 else if(y<=tree[LL(index)].r) Update(LL(index),x,y,val); 46 else if(x>=tree[RR(index)].l) Update(RR(index),x,y,val); 47 else { 48 Update(LL(index),x,tree[LL(index)].r,val); 49 Update(RR(index),tree[RR(index)].l,y,val); 50 } 51 tree[index].sum = tree[LL(index)].sum + tree[RR(index)].sum; 52 } 53 54 int main() 55 { 56 int i, j, x, y, z, n, icase, q, k = 0; 57 scanf("%d",&icase); 58 while(icase--){ 59 scanf("%d",&n); 60 BuildTree(1,1,n); 61 scanf("%d",&q); 62 for(i=0; i<q; ++i){ 63 scanf("%d %d %d",&x,&y,&z); 64 Update(1,x,y,z); 65 } 66 printf("Case %d: The total value of the hook is %d.\n",++k,tree[1].sum); 67 } 68 69 return 0; 70 }

浙公网安备 33010602011771号