poj 1698Just a Hook
题意:题意很简单,说有个肉钩子,长度为n,每一节有个值,初始值都是1,之后告诉你(x,y,z),意思是把x到y的值变为z;之后让你回答总的值。
PS:由于是这是学的第一个线段树成段更新,而notonlysuccess的线段树讲解其实根本不是讲解,只是把代码粘上去了。那不叫讲解,不叫教程,不过学线段树的都是那样走过来的,我也不说废话了。
对于线段树的成段更新,只要是用上了延迟标记。
什么时候用延迟标记呢?我们在update是,当这个update的区间都在我们要更新的区间时,我们就需要用上延迟标记了,此时,标记col[rt]=1;说面需要延迟了。然后再次更新时,这个区间不是要全部更新,那么先调用PushDown,把标记推下去,然后在计算现在需要计算的值。
具体的看代码吧!

1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<iostream> 4 #include<string> 5 #include<queue> 6 #include<map> 7 #include<cmath> 8 #include<stack> 9 #include<algorithm> 10 #include<functional> 11 using namespace std; 12 //1.bulid(); 13 //2.query(a,b) 14 //3.update(a,b) 15 #define lson l , m , rt << 1 16 #define rson m + 1 , r , rt << 1 | 1 17 const int maxn = 100055; 18 int sign[maxn<<2]; 19 int sum[maxn<<2]; 20 int n; 21 //根据题意做相关修改,询问时的操作 22 int operate(int a,int b){ 23 return a+b; 24 } 25 void PushUp(int rt){ 26 sum[rt]=operate(sum[rt<<1],sum[rt<<1|1]); 27 } 28 void PushDown(int rt,int m) { 29 if (sign[rt]) { 30 sign[rt<<1] = sign[rt<<1|1] = sign[rt]; 31 sum[rt<<1] = (m - (m >> 1)) * sign[rt]; 32 sum[rt<<1|1] = (m >> 1) * sign[rt]; 33 sign[rt] = 0; 34 } 35 } 36 void bulid(int l=1,int r=n,int rt=1){ 37 sign[rt] = 0; 38 if(l==r){// 据题意做相关修改 39 sum[rt]=1;return ; 40 } 41 int m=(l+r)>>1; 42 bulid(lson); 43 bulid(rson); 44 PushUp(rt); 45 } 46 void update(int L,int R,int add,int l=1,int r=n,int rt=1){ 47 if(L<=l && r<=R){// 据题意做相关修改 48 sign[rt]=add; 49 sum[rt]=(r-l+1)*add;return ; 50 } 51 PushDown(rt,r-l+1); 52 int m = (l + r) >> 1; 53 if (L <= m) update(L , R , add , lson); 54 if (R > m) update(L , R , add , rson); 55 PushUp(rt); 56 } 57 58 59 int main() 60 { 61 int t,m,x,y,z; 62 scanf("%d",&t); 63 for(int i=1;i<=t;i++){ 64 scanf("%d%d",&n,&m); 65 bulid(); 66 while(m--){ 67 scanf("%d%d%d",&x,&y,&z); 68 update(x,y,z); 69 } 70 printf("Case %d: The total value of the hook is %d.\n",i , sum[1]); 71 } 72 73 return 0; 74 }