1698 Just a Hook 线段树区间更新

来源:互联网 发布:淘宝客转换链接 编辑:程序博客网 时间:2024/06/02 17:51

    线段树区间更新,有个懒惰标记,每次更新不进行到底,,用懒惰标记使得更新延迟到下次需要更新或者询问到的时候。线段树的精髓在于能不向下更新,尽可能利用子树的根的信息去获取整棵子树的信息。

#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#define lson l, m, rt << 1#define rson m+1, r, rt << 1 | 1using namespace std;const int MAXN = 200020;int col[MAXN<<2];//懒惰标记,每次更新到下一次需要更新的或者需要询问的节点int sum[MAXN<<2];void PushUp(int rt){sum[rt] = sum[rt<<1] + sum[rt<<1|1];}void PushDown(int rt, int m)//乡下更新一次,与懒惰标记一起理解{if(col[rt])//col[rt]表明上一次已经更新到rt节点,现在需要向其子节点更新一次{col[rt<<1] = col[rt<<1|1] = col[rt];sum[rt<<1] = col[rt] * (m - (m>>1));sum[rt<<1|1] = col[rt] * (m>>1);col[rt] = 0;}}void Build(int l, int r, int rt){col[rt] = 0;sum[rt] = 1;if(l == r)return;int m = (l+r)>>1;Build(lson);Build(rson);PushUp(rt);}void UpData(int L, int R, int c, int l, int r, int rt){if(L <= l && R >= r){col[rt] = c;sum[rt] = c * (r-l+1);return;}PushDown(rt, r-l+1);int m = (l+r)>>1;if(L <= m)UpData(L, R, c, lson);if(R > m)UpData(L, R, c, rson);PushUp(rt);}int main(){int T, n, Q;int kcase = 1;scanf("%d", &T);while(T--){scanf("%d%d", &n, &Q);Build(1, n, 1);while(Q--){int a, b, c;scanf("%d%d%d",&a, &b, &c);UpData(a, b, c, 1, n, 1);}printf("Case %d: The total value of the hook is %d.\n",kcase++, sum[1]);}system("pause");return 0;}


原创粉丝点击