<题目链接>

题目大意:

给定一段序列,现在对指定区间进行两种操作:一是对指定区间进行修改,对其中的每个数字都开根号(开根号后的数字仍然取整);二是对指定区间进行查询,查询这段区间所有数字的和。

解题分析:

本题虽然是区间修改,但是不需要用 lazy标记,因为要对指定区间的每个数进行开根号的处理,也就是说,每次 update ,都要延伸到该区间涉及到的叶子节点,进行开根,而不是在叶子节点上端的某个节点就将开根的指令存储下来。那么是不是说我们每次只能对 update 的每个区间所涉及到的每个节点进行暴力的单点修改呢?很显然不是的,因为每个节点的值不超过2^63,所以每个值的有效开方次数并不多。所以我们对线段树的每个节点引入一个标记cnt,用它来记录该节点对应的区域是否全部不需要开方,如果不需要开方,那么就直接return ,终止无效更新,从而提高效率。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <algorithm>
  5. using namespace std;
  6.  
  7. #define Lson rt<<1,l,mid
  8. #define Rson rt<<1|1,mid+1,r
  9. typedef long long ll;
  10. const int M = 1e5+;
  11. int n;
  12. ll tr[M<<],arr[M];
  13. bool fp[M<<];
  14. void Pushup(int rt){
  15. if(fp[rt<<]&&fp[rt<<|])fp[rt]=true; //如果两个子区间全部不用开根号的话,那么该区间也标记为不用继续开根
  16. else fp[rt]=false;
  17. tr[rt]=tr[rt<<]+tr[rt<<|];
  18. }
  19. void build(int rt,int l,int r){
  20. if(l==r){
  21. tr[rt]=arr[l];
  22. return;
  23. }
  24. int mid=(l+r)>>;
  25. build(Lson);
  26. build(Rson);
  27. Pushup(rt);
  28. }
  29. void update(int rt,int l,int r,int L,int R){
  30. if(fp[rt])return; //如果遍历到不用继续向下更新的区间,则直接返回
  31. if(l==r){
  32. tr[rt]=sqrt(tr[rt]*1.0);
  33. if(tr[rt]==)fp[rt]=true; //如果tr[rt]==1,那么该点就标记为不用继续开根
  34. return;
  35. }
  36. int mid=(l+r)>>;
  37. if(L<=mid)update(Lson,L,R);
  38. if(R>mid)update(Rson,L,R);
  39. Pushup(rt);
  40. }
  41. ll query(int rt,int l,int r,int L,int R){
  42. if(L<=l&&r<=R){
  43. return tr[rt];
  44. }
  45. int mid=(l+r)>>;
  46. ll ans=;
  47. if(L<=mid)ans+=query(Lson,L,R);
  48. if(R>mid)ans+=query(Rson,L,R);
  49. return ans;
  50. }
  51. int main(){
  52. int ncase=;
  53. while(scanf("%d",&n)!=EOF){
  54. memset(fp,false,sizeof(fp));
  55. for(int i=;i<=n;i++)scanf("%lld",&arr[i]);
  56. build(,,n);
  57. int m;scanf("%d",&m);
  58. printf("Case #%d:\n",++ncase);
  59. while(m--){
  60. int op,x,y;
  61. scanf("%d%d%d",&op,&x,&y);
  62. if(x>y)swap(x,y); //注意这里,坑
  63. if(op==){
  64. update(,,n,x,y);
  65. }
  66. else{
  67. printf("%lld\n",query(,,n,x,y));
  68. }
  69. }
  70. printf("\n");
  71. }
  72. return ;
  73. }

2018-09-23

HDU 4027 Can you answer these queries【线段树】的更多相关文章

  1. hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和

    Can you answer these queries? Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...

  2. HDU 4027 Can you answer these queries? (线段树区间修改查询)

    描述 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to u ...

  3. HDU 4027 Can you answer these queries?(线段树,区间更新,区间查询)

    题目 线段树 简单题意: 区间(单点?)更新,区间求和  更新是区间内的数开根号并向下取整 这道题不用延迟操作 //注意: //1:查询时的区间端点可能前面的比后面的大: //2:优化:因为每次更新都 ...

  4. hdu 4027 Can you answer these queries? 线段树

    线段树+剪枝优化!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> #includ ...

  5. HDU 4027 Can you answer these queries? (线段树成段更新 && 开根操作 && 规律)

    题意 : 给你N个数以及M个操作,操作分两类,第一种输入 "0 l r" 表示将区间[l,r]里的每个数都开根号.第二种输入"1 l r",表示查询区间[l,r ...

  6. hdu 4027 Can you answer these queries?

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4027 Can you answer these queries? Description Proble ...

  7. HDU 4027 Can you answer these queries?(线段树区间开方)

    Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K ...

  8. HDU 4027—— Can you answer these queries?——————【线段树区间开方,区间求和】

    Can you answer these queries? Time Limit:2000MS     Memory Limit:65768KB     64bit IO Format:%I64d & ...

  9. hdu 4027 Can you answer these queries? (区间线段树,区间数开方与求和,经典题目)

    Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K ...

  10. HDU 4027 Can you answer these queries?(线段树的单点更新+区间查询)

    题目链接 题意 : 给你N个数,进行M次操作,0操作是将区间内的每一个数变成自己的平方根(整数),1操作是求区间和. 思路 :单点更新,区间查询,就是要注意在更新的时候要优化,要不然会超时,因为所有的 ...

随机推荐

  1. RemoveDuplicatesfromSortedList

    给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3-&g ...

  2. Java的家庭记账本程序(D)

    日期:2019.2.8 博客期:031 星期一 今天是把程序的查询功能以列表的形式完成了! 截图如下:

  3. LeetCode(76): 最小覆盖子串

    Hard! 题目描述: 给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串. 示例: 输入: S = "ADOBECODEBANC", T = &q ...

  4. mac 显示/不显示"任何来源"_ mac打开安装文件显示文件破损解决办法

    系统: macOS_10.12 导致文件破损原因: 软件有经过了汉化或者破解,所以可能被Mac认为「已损坏」 解决问题办法: 系统偏好设置 -> 安全性与隐私 -> 通用 -> 选择 ...

  5. centos6 防火墙iptables操作整理

    使用语句 前言:  iptables的启动文件位置再:  /etc/init.d/iptables , srevice iptables调用的就是这里的执行文件 查看防火墙状态   service i ...

  6. 基于“MVC”框架集设计模式,开发用户管理系统!

    MVC----(Model View Controller)设计模型: M:表示业务数据和业务规则.包括DAO(beans).DBHelper(DBHelper),用于封装数据库连接,业务数据库处理. ...

  7. Java接口自动化测试之集成MyBatis和MySQL (五)

    pom.xml新增dependency <dependency> <groupId>org.mybatis</groupId> <artifactId> ...

  8. OpenCV-Python入门教程3-图像基本操作(访问像素点/ROI/通道分离)

    一.获取和修改像素点的值 import cv2img = cv2.imread('lena.jpg') # 100, 90表示行列坐标 px = img[100, 90] print(px) # 获取 ...

  9. C#线性表

    线性表是线性结构的抽象 线性结构的特点是结构中的数据元素之间存在一对一的线性关系 一对一的关系指的是数据元素之间的位置关系 (1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素 ( ...

  10. 一脸懵逼学习Hadoop中的序列化机制——流量求和统计MapReduce的程序开发案例——流量求和统计排序

    一:序列化概念 序列化(Serialization)是指把结构化对象转化为字节流.反序列化(Deserialization)是序列化的逆过程.即把字节流转回结构化对象.Java序列化(java.io. ...