题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902

解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是把区间 (l,r) 中大于x的数跟 x 做gcd操作。

线段树区间更新的题目,每个节点保存一个最大和最小值,当该节点的最大值和最小值相等的时候表示这个区间所有的数字都是相同的,可以直接对这个区间进行1或2操作,

进行1操作时,当还没有到达要操作的区间但已经出现了节点的最大值跟最小值相等的情况时,说明这个区间的值都是相同的,但现在我只要在这个区间的一部分进行1操作,所以

我要先把这个节点的最大的最小值往下压,直到找到了要操作的区间。

进行2操作时,如果该区间的最大值都小于x,则可以直接退出,如果最大值大于x,则表示这个区间可以进行gcd操作,然后继续往下,直到找到最大值跟最小值相等的区间才开始

进行gcd操作,进行gcd操作之后不要忘了更新父节点的最大最小值。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. using namespace std;
  6. #define maxn 100005
  7. struct node
  8. {
  9. int Max,Min,l,r;
  10. }tree[*maxn];
  11. void build(int p)
  12. {
  13. if(tree[p].l == tree[p].r) return ;
  14. int mid = (tree[p].l + tree[p].r) / ;
  15. tree[*p].Max = tree[*p+].Max = -;
  16. tree[*p].Min = tree[*p+].Min = 0x7fffffff;
  17. tree[*p].l = tree[p].l;
  18. tree[*p].r = mid;
  19. tree[*p+].l = mid + ;
  20. tree[*p+].r = tree[p].r;
  21. build(*p);
  22. build(*p+);
  23. }
  24. void push(int p,int l,int d)
  25. {
  26. tree[p].Max = max(tree[p].Max,d);
  27. tree[p].Min = min(tree[p].Min,d);
  28. if(tree[p].l == tree[p].r) return ;
  29. int mid = (tree[p].l + tree[p].r) / ;
  30. if(l <= mid) push(*p,l,d);
  31. else push(*p+,l,d);
  32. }
  33. int gcd(int a,int b)
  34. {
  35. return b == ? a : gcd(b,a%b);
  36. }
  37. void oper1(int p,int l,int r,int x)
  38. {
  39. if(tree[p].l == l && tree[p].r == r)
  40. {
  41. tree[p].Max = tree[p].Min = x;
  42. return ;
  43. }
  44. int mid = (tree[p].l + tree[p].r) / ;
  45. if(tree[p].Max == tree[p].Min)
  46. {
  47. oper1(*p+,mid+,tree[p].r,tree[p].Max); //先把当前区间的值往下压
  48. oper1(*p,tree[p].l,mid,tree[p].Max);
  49. }
  50. tree[p].Max = max(tree[p].Max,x);
  51. tree[p].Min = min(tree[p].Min,x);
  52. if(r <= mid)
  53. oper1(*p,l,r,x);
  54. else if(l <= mid && r > mid)
  55. {
  56. oper1(*p,l,mid,x);
  57. oper1(*p+,mid+,r,x);
  58. }
  59. else oper1(*p+,l,r,x);
  60. }
  61. void oper2(int p,int l,int r,int x)
  62. {
  63. int mid = (tree[p].l + tree[p].r) / ;
  64. if(tree[p].l == l && tree[p].r == r)
  65. {
  66. if(tree[p].Max < x) return ; //最大的都不可以进行gcd操作,直接退出
  67. if(tree[p].Max == tree[p].Min) //找到了值都相同的区间,可以直接进行gcd操作
  68. {
  69. if(tree[p].Max > x) tree[p].Max = tree[p].Min = gcd(tree[p].Max,x);
  70. return ;
  71. }
  72. else if(tree[p].Max > x)
  73. {
  74. oper2(*p,l,mid,x);
  75. oper2(*p+,mid+,r,x);
  76. }
  77. return ;
  78. }
  79. if(tree[p].Max == tree[p].Min) //还没找到操作的区间之前碰到了这个,则也要通过1操作,把这个节点的值往下压
  80. {
  81. oper1(*p,tree[p].l,mid,tree[p].Max);
  82. oper1(*p+,mid+,tree[p].r,tree[p].Max);
  83. }
  84. if(r <= mid)
  85. oper2(*p,l,r,x);
  86. else if(l <= mid && r > mid)
  87. {
  88. oper2(*p,l,mid,x);
  89. oper2(*p+,mid+,r,x);
  90. }
  91. else oper2(*p+,l,r,x);
  92. if(tree[p].l != tree[p].r) //记得更新父节点的最大最小值
  93. {
  94. tree[p].Max = max(tree[*p].Max,tree[*p+].Max);
  95. tree[p].Min = min(tree[*p].Min,tree[*p+].Min);
  96. }
  97. }
  98. int query(int p,int l)
  99. {
  100. int mid = (tree[p].l + tree[p].r) / ;
  101. if(tree[p].Max == tree[p].Min)
  102. return tree[p].Max;
  103. if(l <= mid) return query(*p,l);
  104. else return query(*p+,l);
  105. }
  106.  
  107. int main()
  108. {
  109. int T,n;
  110. scanf("%d",&T);
  111. while(T--)
  112. {
  113. scanf("%d",&n);
  114. tree[].Max = -;
  115. tree[].Min = 0x7fffffff;
  116. tree[].l = ;
  117. tree[].r = n;
  118. build();
  119. int d;
  120. for(int i = ;i <= n;++i)
  121. {
  122. scanf("%d",&d);
  123. push(,i,d);
  124. }
  125. int q,t,l,r,x;
  126. scanf("%d",&q);
  127. while(q--)
  128. {
  129. scanf("%d%d%d%d",&t,&l,&r,&x);
  130. if(t == ) oper1(,l,r,x);
  131. else oper2(,l,r,x);
  132. }
  133. for(int i = ;i <= n;++i) //输出有点不同,PE了好几次,最后也是有空格的
  134. printf("%d ",query(,i));
  135. puts("");
  136. }
  137. return ;
  138. }

HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)的更多相关文章

  1. HDU 4941 Magical Forest(map映射+二分查找)杭电多校训练赛第七场1007

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 解题报告:给你一个n*m的矩阵,矩阵的一些方格中有水果,每个水果有一个能量值,现在有三种操作,第 ...

  2. HDU 4864 Task (贪心+STL多集(二分)+邻接表存储)(杭电多校训练赛第一场1004)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4864 解题报告:有n台机器用来完成m个任务,每个任务有一个难度值和一个需要完成的时间,每台机器有一个可 ...

  3. 线段树 + 区间更新: HDU 4893 Wow! Such Sequence!

    Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  4. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  5. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  6. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  7. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

  8. 线段树 + 区间更新 ----- HDU 4902 : Nice boat

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  9. 【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

随机推荐

  1. 深入JVM-性能监控工具

    一.Linux下的性能监控工具 1.1 显式系统整体资源使用情况-top命令 top命令的输出可以分为两个部分:前半部分是系统统计信息,后半部分是进程信息. 在统计信息中,第一行是任务队列信息,他的结 ...

  2. 最小路径(prim)算法

    #include <stdio.h>#include <stdlib.h>/* 最小路径算法 -->prim算法 */#define VNUM 9#define MV 6 ...

  3. Integer 与int 赋值比较

    测试代码: @Test public void IntegerTest() { Integer i01 = 59; int i02 = 59; Integer i03 = Integer.valueO ...

  4. Runner站立会议01

    开会时间:9.10-9.30 地点:二教 今天做了什么:学了文本输入,button按钮,界面转换(意图) 遇到什么困难:界面转换时,出现问题,没有正常跳转 明天打所作什么:解决今天遇到的问题,学了第二 ...

  5. Java数据结构——链表-单链表

    <1>链表 <2>引用和基本类型 <3>单链表 //================================================= // Fil ...

  6. MySQL学习笔记——安装及配置环境

    1.安装的版本为mysql-5.6.24-win32.1432006610压缩版 查看教程http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345b ...

  7. Comet、SSE、技术

    1.概念: 利用长时间保留的HTTP请求(‘挂起的GET’)来让服务器向浏览器推送数据的技术,经常被称为Comet. SSE让服务器可以向客户端流式发送文本消息,比如服务器上生成的实时通知或更新.

  8. C#:String.Format数字格式化输出

    int a = 12345678; //格式为sring输出//   Label1.Text = string.Format("asdfadsf{0}adsfasdf",a);// ...

  9. android 点击屏幕关闭 软键盘

    //点击屏幕 关闭输入弹出框 @Override public boolean onTouchEvent(MotionEvent event) { InputMethodManager im = (I ...

  10. Yii2 使用八 使用scenarios

    在model里定义 public function scenarios() { return [ 'add' => ['title', 'content'], ]; } 在rules里定义 [[ ...