题目链接:点击打开链接
线段树区间更新区间查询,lazy标记模板题。
每次修改某区间时,只需改当前区间,暂时先不修改子区间,而是打一个lazy标记,等到下次query或update时pushdown,按照父节点的lazy更新子节点,给子节点打上标记,再去掉父节点的标记。
代码:
#include <iostream> #include <cstdio> #include <cstring> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define MAX 100010 using namespace std; int sum[MAX<<2]; int col[MAX<<2]; int N,Q; void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void pushdown(int rt,int len){ if(col[rt]){ col[rt<<1]=col[rt<<1|1]=col[rt]; sum[rt<<1]=(len-(len>>1))*col[rt]; sum[rt<<1|1]=(len>>1)*col[rt]; col[rt]=0; } } void build(int l,int r,int rt){ col[rt]=0; if(l==r){ sum[rt]=1; return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt); } int query(int L,int R,int l,int r,int rt){ pushdown(rt,r-l+1); if(L<=l&&R>=r) return sum[rt]; int m=(l+r)<<1; int res=0; if(L<=m) res+=query(L,m,lson); if(R>m) res+=query(m+1,R,rson); pushup(rt); return res; } void update(int L,int R,int k,int l,int r,int rt){ if(L<=l&&R>=r){ col[rt]=k; sum[rt]=(r-l+1)*k; return ; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m) update(L,R,k,lson); if(R>m) update(L,R,k,rson); pushup(rt); } int main(){ int T; cin>>T; int cas=1; while(T--){ scanf("%d%d",&N,&Q); build(1,N,1); int x,y,z; for(int i=1;i<=Q;i++){ scanf("%d%d%d",&x,&y,&z); update(x,y,z,1,N,1); } printf("Case %d: The total value of the hook is %d.\n",cas++,sum[1]); } return 0; }