题目分析

  题意:每个点都有一个值$v_i$,从一个点出发,每走到一个点,会跳到i+vi的位置,问需要跳多少次能跳出n?带修改。

  此题可以用lct做,此处使用了分块:将序列分块后,每个点记录从此点最少跳几次能跳出当前块,和跳出后到达的位置,倒叙可以优化。

  这样询问时只要一直跳至多$\sqrt{n}$个块就能知道答案。

  对于修改操作,只需将修改点和修改点之前的当前块元素重新使用上述处理,同样倒叙可以优化。

code

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<string>
  6. #include<algorithm>
  7. #include<cmath>
  8. #include<vector>
  9. using namespace std;
  10.  
  11. const int N = 2e5 + ;
  12. int n, m, S;
  13. int blkCnt, blk[N], bl[], br[];
  14. long long val[N], step[N], des[N];
  15.  
  16. inline int read(){
  17. int i = , f = ; char ch = getchar();
  18. for(; (ch < '' || ch > '') && ch != '-'; ch = getchar());
  19. if(ch == '-') f = -, ch = getchar();
  20. for(; ch >= '' && ch <= ''; ch = getchar())
  21. i = (i << ) + (i << ) + (ch - '');
  22. return i * f;
  23. }
  24.  
  25. inline long long readL(){
  26. long long i = , f = ; char ch = getchar();
  27. for(; (ch < '' || ch > '') && ch != '-'; ch = getchar());
  28. if(ch == '-') f = -, ch = getchar();
  29. for(; ch >= '' && ch <= ''; ch = getchar())
  30. i = (i << ) + (i << ) + (ch - '');
  31. return i * f;
  32. }
  33.  
  34. inline void wr(long long x){
  35. if(x < ) putchar('-'), x = -x;
  36. if(x > ) wr(x / );
  37. putchar(x % + '');
  38. }
  39.  
  40. inline void init(){
  41. bl[blkCnt = ] = ;
  42. for(int i = ; i <= n; i++){
  43. if(i % S == ){
  44. br[blkCnt] = i;
  45. blk[i] = blkCnt;
  46. if(i + <= n){
  47. bl[++blkCnt] = i + ;
  48. continue;
  49. }
  50. }
  51. blk[i] = blkCnt;
  52. }
  53. br[blkCnt] = n;
  54. }
  55.  
  56. int main(){
  57. n = read(), S = sqrt(n);
  58. for(int i = ; i <= n; i++) val[i] = readL();
  59. init();
  60. for(int i = n; i >= ; i--){
  61. int tmp = i;
  62. bool flag = false;
  63. step[i] = ;
  64. while(tmp + val[tmp] <= br[blk[i]]){
  65. tmp += val[tmp], step[i]++;
  66. if(step[tmp]){
  67. step[i] += step[tmp], des[i] = des[tmp], flag = true;
  68. break;
  69. }
  70. }
  71. if(!flag) des[i] = tmp + val[tmp], step[i]++;
  72. }
  73. m = read();
  74. for(int t = ; t <= m; t++){
  75. int opt = read();
  76. if(opt == ){
  77. int src = read() + , ans = , tmp;
  78. tmp = src;
  79. while(des[tmp] <= n) ans += step[tmp], tmp = des[tmp];
  80. ans += step[tmp];
  81. wr(ans), putchar('\n');
  82. }
  83. else{
  84. int pos = read() + , value = readL();
  85. if(val[pos] == value) continue;
  86. val[pos] = value;
  87. for(int i = bl[blk[pos]]; i <= pos; i++) step[i] = ;
  88.  
  89. for(int i = pos; i >= bl[blk[pos]]; i--){
  90. int tmp = i; bool flag = false;
  91. while(tmp + val[tmp] <= br[blk[pos]]){
  92. tmp += val[tmp], step[i]++;
  93. if(step[tmp]){
  94. step[i] += step[tmp], des[i] = des[tmp], flag = true;
  95. break;
  96. }
  97. }
  98. if(!flag) des[i] = tmp + val[tmp], step[i]++;
  99. }
  100. }
  101. }
  102. return ;
  103. }

【bzoj2002】弹飞绵羊(分块)的更多相关文章

  1. bzoj2002 弹飞绵羊 分块

    这道题是分块的初尝试 讲给定的区间n进行分块处理 这个每次修改的复杂的只有logn 很方便 代码是学黄学长的 http://hzwer.com/3505.html 当然里面还是有一定我自己的想法在里面 ...

  2. P3203 弹飞绵羊-分块

    P3203 弹飞绵羊-分块 观察数据范围,发现可以分块.只需要处理每个点跳出所在块后的位置和次数即可.目的是为了加速查询并降低修改复杂度. 对于修改,重构整个块内信息即可. 时间复杂度正确的一批 具体 ...

  3. 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊 分块

    [bzoj2002][Hnoi2010]Bounce 弹飞绵羊 2014年7月30日8101 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀 ...

  4. BZOJ-2002 弹飞绵羊 Link-Cut-Tree (分块)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 6801 Solved: 3573 [Submi ...

  5. 【BZOJ2002】【HNOI2010】弹飞绵羊 [分块]

    弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MB[Submit][Status][Discuss] Description 某天,Lostmonkey发明了一 ...

  6. 【BZOJ 2002】【Hnoi 2010】弹飞绵羊 分块||Link Cut Tree 两种方法

    ShallWe,Yveh,hmy,DaD3zZ,四人吃冰糕从SLYZ超市出来后在马路上一字排开,,,吃完后发现冰糕棍上写着:“向狮子座表白:愿做你的小绵羊”,,, 好吧在这道题里我们要弹飞绵羊,有分块 ...

  7. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  8. BZOJ 2002 Bounce 弹飞绵羊 (分块或动态树)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 13768  Solved: 6989[Subm ...

  9. [HNOI2010] 弹飞绵羊 (分块)

    [HNOI2010] 弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上 ...

  10. BZOJ 2002 Bounce 弹飞绵羊 —— 分块算法

    题目链接:https://vjudge.net/problem/HYSBZ-2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Li ...

随机推荐

  1. FMS2015:NVMe SSD的高可靠性及数据保护

    FMS2015是一个充满技术干货的平台,各领域技术大拿在峰会上分享的技术和产品都影响甚至主导着闪存下一阶段的发展. 此次Memblaze的project师团队也是从存储系统.PCIe SSD以及闪存控 ...

  2. 【CodeForces】Gargari and Bishops

    依据贪心能够知道,放置的教主必须不能相互攻击到(也就是不在一条对角线上)才干够使得结果最大化. 依据观察能够得到教主相互不攻击的条件是他的坐标和互为奇偶(x + y) 之后直接暴力,处理每一个坐标对角 ...

  3. js进阶 14-2 如何用ajax验证登陆状态(这里用load方法)

    js进阶 14-2 如何用ajax验证登陆状态(这里用load方法) 一.总结 一句话总结:$('#test').load('test.php?password=1234560'),这样就get方式提 ...

  4. 支付宝支付返回通知时 notify_url和return_url的选择

    页面跳转同步通知页面特性(return_url特性) 买家在支付成功后会看到一个支付宝交易提示成功的页面,该页面会停留几秒,然后会自动跳转回商户指定的同步通知页面(参数return_url) 该页面中 ...

  5. IOS开发常用的开源组件

    .AFNetworking是一个开源的网络库 .EGORefreshTableHeaderView是一个实现向下拉刷新列表的组件 .MBProgressHUD是一个进度显示的组件 .EGOImageL ...

  6. 各种排序算法的分析及java实现 分类: B10_计算机基础 2015-02-03 20:09 186人阅读 评论(0) 收藏

    转载自:http://www.cnblogs.com/liuling/p/2013-7-24-01.html 另可参考:http://gengning938.blog.163.com/blog/sta ...

  7. php面试题二--解决网站大流量高并发方案(从url到硬盘来解决高并发方案总结)

    php面试题二--解决网站大流量高并发方案(从url到硬盘来解决高并发方案总结) 一.总结 从外到内解决网站大流量高并发问题---从提交一个url开始(从用户按下搜索栏回车键开始) url最开始会到d ...

  8. ModSecurity防御暴力破解

    http://www.modsecurity.org/ ModSecurity防御暴力破解 在阅读本文前,先简单了解下什么是ModSecurity,ModSecurity是一个入侵探测与阻止的引擎.它 ...

  9. php实现Bloom Filter

    Bloom Filter(BF) 是由Bloom在1970年提出的一种多哈希函数映射的高速查找算法,用于高速查找某个元素是否属于集合, 但不要求百分百的准确率. Bloom filter通经常使用于爬 ...

  10. [AngularFire2] Build a Custom Node Backend Using Firebase Queue

    In this lesson we are going to learn how to build a custom Node process for batch processing of Fire ...