补这题主要是因为第三个操作要维护区间,而不是点,否则会T。

https://vjudge.net/problem/HDU-4893

题意:输入n、q。表示有n个数,初始化默认这n个数都为零,有q次操作,操作种类分为三种:1、输入k,d,使得k位置的数加上d。2、输入l,r,求区间[l,r]的和并输出。3、输入l,r,把区间[l,r]内的数都改成斐波拉契数,修改方式为使得fabs[x-F[i]]最小,如果有多个F[i]满足情况,用最小的那个F[i]。1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, |d| < 231

做法:对于前两种操作,可以用单点更新来维护,但是对于第三种操作如果用单点更新的话,会TLE(n^2),所以我们要区间更新,我们要很快的知道区间[l,r]区间的FIB和,索性我们就在线段树里维护所有数的FIB和,在build,和操作一的时候更新就可以了。时间复杂度n*log(n)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. const int maxn = 100050;
  5. int n, m;
  6. struct node
  7. {
  8. int l, r;
  9. LL sm1, sm2;
  10. bool t;
  11. } T[maxn << 2];
  12. LL F[150];
  13. void init()
  14. {
  15. F[0] = F[1] = 1;
  16. for(int i = 2; i <= 90; i++)
  17. F[i] = F[i - 1] + F[i - 2];
  18. }
  19. LL FBI(LL x)
  20. {
  21. int pos = (int)(lower_bound(F, F + 80, x) - F);
  22. if(!pos) return F[0];
  23. else
  24. {
  25. LL t1 = F[pos] - x;
  26. LL t2 = x - F[pos - 1];
  27. if(t1 < t2)
  28. return F[pos];
  29. else
  30. return F[pos - 1];
  31. }
  32. }
  33. void pushup(int id)
  34. {
  35. T[id].sm1 = T[id << 1].sm1 + T[id << 1 | 1].sm1;
  36. T[id].sm2 = T[id << 1].sm2 + T[id << 1 | 1].sm2;
  37. }
  38. void pushdown(int id)
  39. {
  40. if(T[id].t)
  41. {
  42. T[id << 1].sm1 = T[id << 1].sm2;
  43. T[id << 1].t = 1;
  44. T[id << 1 | 1].sm1 = T[id << 1 | 1].sm2;
  45. T[id << 1 | 1].t = 1;
  46. T[id].t = 0;
  47. }
  48. }
  49. void build(int id, int l, int r)
  50. {
  51. T[id].l = l;
  52. T[id].r = r;
  53. T[id].t = 0;
  54. if(l == r)
  55. {
  56. T[id].sm1 = 0;
  57. T[id].sm2 = 1;
  58. return ;
  59. }
  60. else
  61. {
  62. int mid = (l + r) >> 1;
  63. build(id << 1, l, mid);
  64. build(id << 1 | 1, mid + 1, r);
  65. pushup(id);
  66. }
  67. }
  68. LL sum(int id, int l, int r)
  69. {
  70. if(T[id].l == l && T[id].r == r)
  71. return T[id].sm1;
  72. else
  73. {
  74. pushdown(id);
  75. int mid = (T[id].l + T[id].r) >> 1;
  76. if(r <= mid)
  77. return sum(id << 1, l, r);
  78. else if(l >= mid + 1)
  79. return sum(id << 1 | 1, l, r);
  80. else
  81. return sum(id << 1, l, mid) + sum(id << 1 | 1, mid + 1, r);
  82. }
  83. }
  84. void change(int id, int l, int r)
  85. {
  86. if(T[id].l == l && T[id].r == r)
  87. {
  88. T[id].sm1 = T[id].sm2;
  89. T[id].t = 1;
  90. return ;
  91. }
  92. else
  93. {
  94. pushdown(id);
  95. int mid = (T[id].l + T[id].r) >> 1;
  96. if(r <= mid)
  97. {
  98. change(id << 1, l, r);
  99. }
  100. else if(l >= mid + 1)
  101. {
  102. change(id << 1 | 1, l, r);
  103. }
  104. else
  105. {
  106. change(id << 1, l, mid);
  107. change(id << 1 | 1, mid + 1, r);
  108. }
  109. pushup(id);
  110. }
  111. }
  112. void update(int id, int pos, LL d)
  113. {
  114. if(T[id].l == T[id].r)
  115. {
  116. T[id].sm1 += d;
  117. T[id].sm2 = FBI(T[id].sm1);
  118. return ;
  119. }
  120. else
  121. {
  122. pushdown(id);
  123. int mid = (T[id].l + T[id].r) >> 1;
  124. if(pos <= mid)
  125. update(id << 1, pos, d);
  126. else
  127. update(id << 1 | 1, pos, d);
  128. pushup(id);
  129. }
  130. }
  131. int main()
  132. {
  133. init();
  134. while(scanf("%d%d", &n, &m) != EOF)
  135. {
  136. build(1, 1, n);//
  137. LL d;
  138. int k, l, r, ty;
  139. for(int i = 1; i <= m; i++)
  140. {
  141. scanf("%d", &ty);
  142. if(ty == 1)
  143. {
  144. scanf("%d%lld", &k, &d);
  145. update(1, k, d);
  146. }
  147. else if(ty == 2)
  148. {
  149. scanf("%d%d", &l, &r);
  150. printf("%lld\n", sum(1, l, r));
  151. }
  152. else
  153. {
  154. scanf("%d%d", &l, &r);
  155. change(1, l, r);
  156. }
  157. }
  158. }
  159. return 0;
  160. }

2019hdu多校3 hdu4893(线段树单点 区间更新的更多相关文章

  1. 蓝桥杯Log大侠(线段树单点区间更新)

    标题:Log大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... 变换的规则是: ...

  2. hdu 1556:Color the ball(线段树,区间更新,经典题)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. hdu 1698:Just a Hook(线段树,区间更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. UVA 12436-Rip Van Winkle's Code(线段树的区间更新)

    题意: long long data[250001]; void A( int st, int nd ) { for( int i = st; i \le nd; i++ ) data[i] = da ...

  5. hdu1698线段树的区间更新区间查询

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. HDU 1556 Color the ball(线段树:区间更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=1556 题意: N个气球,每次[a,b]之间的气球涂一次色,统计每个气球涂色的次数. 思路: 这道题目用树状数组和 ...

  7. zoj3686(线段树的区间更新)

    对线段树的区间更新有了初步的了解... A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a ...

  8. Color the ball (线段树的区间更新问题)

    N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色.但 ...

  9. ZOJ 2301 Color the Ball 线段树(区间更新+离散化)

    Color the Ball Time Limit: 2 Seconds      Memory Limit: 65536 KB There are infinite balls in a line ...

随机推荐

  1. 电脑新安装JDK版本并运行使用该JDK版本问题

    情景:电脑上已正常安装一个jdk版本,如:1.7.0_71,因考虑到一些情况,现需要使用版本为1.7.0_80(1.8),故需新安装JDK,并使服务可以运行使用新安装的JDK版本. 网络找寻方法: ( ...

  2. 使用struts2的内置标签,采用submit()提交表单时,浏览器报404

    如图 url是没有问题的,结果我将提交方式改为get时,发现有2个参数的name值是一样的,如下图, 解决方法:将name的值修改就OK了.

  3. 170817关于Listener的知识点

    1.  Listener   监听器简介                    Listener是JavaWeb中三大组件之一.Servlet.Filter.Listener              ...

  4. 洛谷P4124 手机号码

    传送 这题也就是条件限制多了点,也没有别的,套板子就好了 注意这里没有前导零,所以第一位是从1开始填 看注释叭 #include<iostream> #include<cstdio& ...

  5. (转)Jquery之ShowLoading遮罩组件

    本文转载自:http://www.cnblogs.com/eczhou/archive/2012/12/18/2822788.html 一.遮罩用途及效果 ShowLoading这个jQuery插件设 ...

  6. Linux_DHCP&DHCP Relay

    目录 目录 DHCP DHCP Relay Setup DHCPServer Setup ClientPort DHCPDHCPRelay Setup DHCPRelay service DHCP D ...

  7. REACT--》fetch---基本使用

    [WangQI]---fetch---基本使用   一.fetch fetch是一种XMLHttpRequest的一种替代方案,在工作当中除了用ajax获取后台数据外我们还可以使用fetch.axio ...

  8. Netty解码的艺术

    什么是拆包/粘包: TCP 粘包/拆包: TCP 是一个“流”协议,所谓流,就是没有界限的一长串二进制数据.TCP 作为传输层协议并不了解上层业务数据的具体含义,它会根据TCP 缓冲区的实际情况进行数 ...

  9. Linux下修改时间及date使用

    [root@host1 ~]# date #显示时间 2017年 06月 01日 星期四 17:02:59 CST 以指定格式显示时间: [root@host1 ~]# date +%Y%m%d 20 ...

  10. py基础

    基本语句和函数等练习,知识点都在代码里... """ a = int(input('a = ')) b = int(input('b = ')) print('%d + ...