标签:maxv 线段 mxtag k1 tag max hismx 最值 小记
线段树历史区间最值:支持区间加法,询问区间内历史上的最大值,清空历史
不要草率!!!比看上去的要难无数倍!!!
注意事项:
1. 一定要记录两个标记 $tag$ 和 $mxtag$,分别为“区间加标记”和“区间最大加标记”(后者也可以理解为这个区间内所有来过的加标记的前缀最大值)
2. 正确的 pushdown 方法:
void pushdown(int k) { if(tag[k]||mxtag[k]){ // !!!X: if(tag[k]) mxtag[k1]=max(mxtag[k1],tag[k1]+mxtag[k]); // !!!X: mxtag[k1]+=mxtag[k] / mxtag[k1]=max(mxtag[k1],tag[k1]+tag[k]) tag[k1]+=tag[k]; hismx[k1]=max(hismx[k1],maxv[k1]+mxtag[k]); // !!!X: hismx[k1]=max(hismx[k1],maxv[k1]) / hismx[k1]=max(hismx[k1],maxv[k1]+tag[k]) maxv[k1]+=tag[k]; // !!!X: maxv[k1]+=mxtag[k] mxtag[k2]=max(mxtag[k2],tag[k2]+mxtag[k]); tag[k2]+=tag[k]; hismx[k2]=max(hismx[k2],maxv[k2]+mxtag[k]); maxv[k2]+=tag[k]; tag[k]=mxtag[k]=0; } }
今天,你死亡了吗
3. 正确的 update 方法:
maxv[k]=max(maxv[k1],maxv[k2]); //!!!X hismx[k]=max(hismx[k],maxv[k]); hismx[k]=max(hismx[k1],hismx[k2]);
4. 在 $[x1,x2]$ 时间修改 $[y1,y2]$,在 $x$ 时间询问 $[y1,y2]$,用的就是这个历史最值线段树,普通线段树搞不定!!!
5. 清空的方法:全局加上一个很大的值 $Delta$(注意 $Delta$ 一定要很大,大于所有修改加之和) ,这样以前的历史最值都被它所淹没了,只留下当下的最值还有效,然后询问时结果减回 $Delta$ 即可。
标签:maxv,线段,mxtag,k1,tag,max,hismx,最值,小记 来源: https://www.cnblogs.com/Charlie-Vinnie/p/15860657.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。