题目:http://acm.hdu.edu.cn/showproblem.php?pid=1698

数据:case,n,q,q行x,y,z。在长度为n的hook上进行q次区间更新,把它们的价值改变。最后统计总的价值。x,y,z分别表示把[x,y]内的hook变成价值为z的hook。

开始写它时,对于样例程序运行的结果总是20,我就纳闷了,怎么改都不对,在反复研究中发现了这样一个问题(bug源于update函数):

void update(int a,int b,int root,int tg){if(a==tree[root].l&&b==tree[root].r){tree[root].tag=tg;tree[root].val=(tree[root].r-tree[root].l+1)*tree[root].tag;return ;}int m=tree[root].mid();if(a>m) update(a,b,2*root+1,tg);else if(b<=m) update(a,b,2*root,tg);else {update(a,m,2*root,tg);update(m+1,b,2*root+1,tg);}tree[root].val=tree[2*root].val+tree[2*root+1].val;
}

我设置了这样的输入:
2
10
2
1 5 2
5 9 3
10
1
1 5 2
也就是第二个输入比第一个输入少了第二步5 9 3,其他都一样,产生的结果是20; 15.我将所有的数据统统输出来,画出线段树:
(1):

(2):

啊,操作一和操作二都有作用,但在样例一中操作二把操作一的数据污染了,也就是新插入5~9中的5那一点让10直接变成了7不是加上1。所以,在update函数里有必要对 懒惰标记不是初始化数据的情况下再对其子树进行处理。如更新第5个点时,势必会先过原val=10的父节点,把它的左子树val变成6,再对右子树处理:left=2, right=3, myval=5,再向上传:
(3):

嘿嘿,应该不会犯错了:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1e5+5;
#define l_t 2*root
#define r_t 2*root+1
struct node{int l,r,val,tag;  //tag:1 2 3 -1int mid(){  return (l+r)/2; }
}tree[maxn<<2];
void update(int a,int b,int root,int tg){if(a==tree[root].l&&b==tree[root].r){tree[root].tag=tg;tree[root].val=(tree[root].r-tree[root].l+1)*tg;return ;}if(tree[root].tag!=-1){tree[l_t].tag=tree[root].tag;tree[l_t].val=tree[l_t].tag*(tree[l_t].r-tree[l_t].l+1);tree[r_t].tag=tree[root].tag;tree[r_t].val=tree[r_t].tag*(tree[r_t].r-tree[r_t].l+1);tree[root].tag=-1;}int m=tree[root].mid();if(a>m) update(a,b,r_t,tg);else if(b<=m) update(a,b,l_t,tg);else {update(a,m,l_t,tg);update(m+1,b,r_t,tg);}tree[root].val=tree[l_t].val+tree[r_t].val;
}
void build(int l,int r,int root){tree[root].l=l;tree[root].r=r;tree[root].tag=-1;if(r==l){tree[root].val=1;return ;}int mid=(l+r)/2;build(l,mid,l_t);build(mid+1,r,r_t);tree[root].val=tree[l_t].val+tree[r_t].val;
}int main()
{//freopen("cin.txt","r",stdin);int ca;cin>>ca;for(int k=1;k<=ca;k++){int n,q;scanf("%d",&n);build(1,n,1);scanf("%d",&q);for(int i=0;i<q;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);update(x,y,1,z);}printf("Case %d: The total value of the hook is %d.\n",k,tree[1].val);}return 0;
}

hdu 1698 Just a Hook(线段树区间更新·经典)相关推荐

  1. hdu 1698 Just a Hook 线段树区间更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 Let us number the consecutive metallic sticks of ...

  2. HDU 1698 Just a Hook (线段树区间修改+区间查询)

    题目链接: 传送门 题意:Pudge对装备钩子进行若干次的强化,强化分为三种分别对应的价值是1,2,3,在经历过若干次操作后,输出钩子对应的总价值,每次强化都是对钩子进行区间修改 解题思路:在明白了题 ...

  3. hdu 5692 Snacks(dfs序+线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5692 解题思路:这道题是树节点的点权更新,而且涉及到子树,常用的思路是利用dfs序,用线段树来对区间进 ...

  4. HDU 1698 Just a Hook 线段树

    区间更新中 lazy标记的pushdown操作 风格还是傻崽的...感觉很好用... /********************* Template ************************/ ...

  5. 2014多校第四场1006 || HDU 4902 Nice boat (线段树 区间更新)

    题目链接 题意 : 给你n个初值,然后进行两种操作,第一种操作是将(L,R)这一区间上所有的数变成x,第二种操作是将(L,R)这一区间上所有大于x的数a[i]变成gcd(x,a[i]).输出最后n个数 ...

  6. hdu 1556 Color the ball 线段树 区间更新

    水一下 #include <bits/stdc++.h> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 ...

  7. POJ 2777 ZOJ 1610 HDU 1698 --线段树--区间更新

    直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 ...

  8. hdu 1698(线段树区间更新)

    解题思路:线段树区间更新水题. #include<iostream> #include<cstdio> #include<cstring> using namesp ...

  9. Just a Hook(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 In the game of DotA, Pudge's meat hook is actual ...

最新文章

  1. python 判断字符串是否包含另一个字符串_强烈推荐:Python字符串(string)方法整理(一)...
  2. Android之matrix类控制图片的旋转、缩放、移动
  3. iOS给图片打水印,并将打过水印的图片生成到沙盒中
  4. C语言for循环的嵌套例题,c语言 for循环的嵌套(含答案)
  5. php网站跨站脚本监测,基于PHP的在线跨站脚本检测工具.pdf
  6. html插入精灵,帮助插入超链接到CSS精灵代码..Java? HTML?
  7. Promise 解决同步请求问题
  8. VS 2017 + EF6 + MySQL5.7 建立实体模型闪退问题
  9. 软件发布!DOTA2统计学
  10. excel 比对多列数据
  11. 基于simhash的短文本去重
  12. flv格式怎么转换成mp4?视频格式转换步骤详解
  13. Uni-app APP开发、适配指北
  14. bonobo server 自定义
  15. 微信支付与微信转账的区别
  16. 咕泡P6:ElasticStack高级开发与架构(实战班)二期
  17. 在服务器上利用mmdetection来训练自己的voc数据集
  18. 【情感识别】SVM语音情感识别(带面板)【含GUI Matlab源码 876期】
  19. aosp编译设备树文件dtbo.img
  20. Emmet语法及使用介绍

热门文章

  1. Git之GitFlow工作流 | Gitflow Workflow(万字整理,已是最详)
  2. 用C语言将16个数存放到40H中,单片机应用技术C语言试题
  3. 小米智能插座采用Marvell EZ-Connect芯片解决方案--88MC200微控制器、Avastar 88W8801
  4. 板式家具包装三步法_板式家具三合一连接件安装方法图解 安帝斯家具五金
  5. SSM框架——Mybatis增删改查
  6. mysql timestamp year_MySQL 的日期类型有5个,分别是: date、time、year、datetime、timestamp。...
  7. Jmeter压测工具的使用
  8. CS229 SVM 推导和使用心得
  9. Vivado 2018.3入门教程(三):生成比特流文件+硬件连接
  10. vue升级uglifyjs