【解题报告】 HDU 1698 Just a Hook 线段树 (线段替换) 插线问线 + 延时标记
2012-08-10 12:12
501 查看
// HDU 1698 Just a Hook 线段树(线段替换)插线插线+ 延时标记 // 延时标记:起一个缓冲的作用,第一次遇到的更新先不更新到底,等下一次更新或者查询的时候再更新到位。 // 因此线段树结构中的区间和 并不是实际值。 // 此处的更新到位是指 本次更新或查询所需的最后一层(因为我查的不是点,而是区间),并非到最底层 // 延时标记下沉的前提:线段树结构中遇到了一个区间完全的包含于待更新区间,即遇到一个待更新区间的子区间 // 注意的是: // 1.下沉这个标记的时候也要更新区间的实际和,下沉过的标记要及时取消 // 2.递归网上弹准备跳出的时候应该顺便更新区间的实际和,也就是把孩子的两个区间实际和相加 // 3.往左或者往右需要进行深层递归的条件:该区间的子区间与待更新区间存在交集 // 4.对我自己要说的,由于是先更新左区间,因此对右区间的更新不受影响,那么待更新的区间就不需要分割了 // /*test data 1 10 4 1 5 2 5 9 3 1 1 1 10 10 1 out = 23 */ #include <stdio.h> #include <string.h> #include <math.h> const int M = 400001; struct NODE{ int value; int left,right; // 其实这两个区间端点都可以不用存起来 int buffer; // 延时标记。 }node[M]; void BuildTree(int i,int left, int right){ node[i].left = left; node[i].right = right; node[i].value = node[i].right - node[i].left + 1; node[i].buffer = 0; if (node[i].left == node[i].right){ return ; } BuildTree(i<<1,left,(left+right)/2); BuildTree((i<<1)+1,(left+right)/2+1,right); } int a,b,v; // updata interval = [a,b] void UpdataTree(int i){ // only revise the buffer if (a <= node[i].left && node[i].right <= b){ // if find a interval contained goal interval completely node[i].value = (node[i].right - node[i].left + 1 ) * v; if (node[i].left != node[i].right) // 末结点不需要延时标记 node[i].buffer = v; // replace return; } if (node[i].buffer){ // if exsit buffer int l = i << 1; node[l].buffer = node[l+1].buffer = node[i].buffer; // Make buffer sinking node[i].buffer = 0; node[l].value = (node[l].right - node[l].left + 1 ) * node[l].buffer; // 左孩子,利用buffer完成上一次未完成的更新 l++; node[l].value = (node[l].right - node[l].left + 1 ) * node[l].buffer; // 右孩子,利用buffer完成上一次未完成的更新 } if (a <= node[i<<1].right) // ***由于先执行的左边,所以待更新区间无需分割,并不影响右边的执行**** /// UpdataTree(i<<1); if (b >= node[(i<<1)+1].left) UpdataTree((i<<1)+1); // finally, this node will be the sum of the two child node[i].value = node[i<<1].value + node[(i<<1)+1].value; } int main(){ freopen("in.txt","r",stdin); int ncase,d=1; scanf("%d",&ncase); while(ncase--){ int nn,n_u; scanf("%d%d",&nn,&n_u); BuildTree(1,1,nn); while(n_u--){ // updata scanf("%d%d%d",&a,&b,&v); UpdataTree(1); // start from NO.1 interval to updata interval [1,nn] by increase v } printf("Case %d: The total value of the hook is %d.\n",d++,node[1].value); } return 0; }
相关文章推荐
- hdu1698 Just a Hook 线段树区间更新,延时标记
- HDU 1698 JUST a hook (线段树 成段替换 区间求和 延迟标记)
- hdu1698-Just a Hook-线段树-整段区间的替换(延迟标记)
- HDU 1698 Just a Hook(线段树区间替换)
- HDU 1698 Just a Hook 线段树 成段替换
- hdu 1698 Just a Hook(线段树,成段更新,懒惰标记)
- hdu1698 Just a Hook(成段替换 lazy标记)
- HDU 1698 Just a Hook (线段树:成段替换)
- HDU 1698 Just a Hook (线段树延迟标记(lazy))
- HDU 1698 Just a Hook 线段树 区间更新 惰性标记
- hdu 1698 Just a Hook (线段树区间更新+懒惰标记)
- HDU 1698 Just a Hook(线段树区间替换)
- hdu1698 Just a Hook (线段树功能:成段替换,总区间求和)
- HDU 1698——Just a Hook——————【线段树区间替换、区间求和】
- [ACM] hdu 1698 Just a Hook (线段树,成段更新,懒惰标记)
- [ACM] hdu 1698 Just a Hook (线段树,成段更新,懒惰标记)
- HDU 1698 Just a Hook(线段树区间替换)
- [ACM] hdu 1698 Just a Hook (线段树,成段更新,懒惰标记)
- HDU 1698 Just a Hook(线段树的区间更新《标记》)
- HDU 1698 Just a Hook 解题报告