线段树成段更新:
昨天看了一晚上,不太理解,自己感觉弱爆了,今早想了想,发现成段更新和单点更新差不多,区别在于单点更新时,往下更新一直更新到叶子节点,成段跟新时,不必更新到叶子节点,当对一个区间操作完成之后,不在往下更新,当每次查询或者修改该区间时,在往下更新。提高了效率。
#include<iostream> #include<algorithm> #include<cstdio> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int Max=100100; int n,m,t,x,y,z; int sum[Max<<2]; int op[Max<<2]; void PushUp(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void PushDown(int rt,int len) { if(op[rt]) { op[rt<<1]+=op[rt]; op[rt<<1|1]+=op[rt]; sum[rt<<1]=(len-(len>>1))*op[rt]; sum[rt<<1|1]=(len>>1)*op[rt]; op[rt]=0; } } void build(int l,int r,int rt) { op[rt]=0; sum[rt]=1; if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson); PushUp(rt); } void Update(int L,int R,int C,int l,int r,int rt) { if(L<=l&&r<=R) { op[rt]+=C; sum[rt]=C*(r-l+1); return; } PushDown(rt,r-l+1); int m=(l+r)>>1; if(L<=m) Update(L,R,C,lson); if(R>m) Update(L,R,C,rson); PushUp(rt); } int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%d",&m); build(1,m,1); scanf("%d",&t); for(int j=0; j<t; j++) { scanf("%d%d%d",&x,&y,&z); Update(x,y,z,1,m,1); } printf("Case %d: The total value of the hook is %d.\n",i,sum[1]); } return 0; }