题意:有n个数初始值都为1,m个操作a,b,c,表示把区间[a,b]变为c,求最后n个数的和。
经典区间更新求和问题,需要用到延迟标记(或者说是懒惰标记),简单老说就是每次更新
的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新或询问的时候。
#include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #include<iostream> #include <queue> #include <stack> #include<algorithm> #include<set> using namespace std; #define INF 1e8 #define eps 1e-8 #define LL long long #define maxn 200005 #define mod 1000000009 struct Tree { int l,r,sum,lazy; }tree[maxn<<2]; void PushUp(int rt) { tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; } void PushDown(int rt) { if(tree[rt].lazy) { tree[rt<<1].lazy=tree[rt<<1|1].lazy=tree[rt].lazy; tree[rt<<1].sum=(tree[rt<<1].r-tree[rt<<1].l+1)*tree[rt].lazy; tree[rt<<1|1].sum=(tree[rt<<1|1].r-tree[rt<<1|1].l+1)*tree[rt].lazy; tree[rt].lazy=0; } } void build(int rt,int l,int r) { tree[rt].l=l;tree[rt].r=r; tree[rt].sum=0;tree[rt].lazy=0; if(l==r) { tree[rt].sum=1; return ; } int mid=(l+r)>>1; build(rt*2,l,mid); build(rt*2+1,mid+1,r); PushUp(rt); } void update(int rt,int l,int r,int v) { if(tree[rt].l>=l&&tree[rt].r<=r) { tree[rt].lazy=v; tree[rt].sum=(tree[rt].r-tree[rt].l+1)*v; return; } PushDown(rt); int mid=(tree[rt].l+tree[rt].r)>>1; if(mid>=r) update(rt*2,l,r,v); else if(mid<l) update(rt*2+1,l,r,v); else { update(rt*2,l,mid,v); update(rt*2+1,mid+1,r,v); } PushUp(rt); } int main() { int t,ca=1; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); build(1,1,n); int a,b,c; while(m--) { scanf("%d%d%d",&a,&b,&c); update(1,a,b,c); } printf("Case %d: The total value of the hook is %d.\n",ca++,tree[1].sum); } return 0; }
HDU 1698 Just a Hook (线段树延迟标记(lazy))
时间: 2024-10-29 11:03:31