首先想到线段树,然后刚开始写忽然想到树状数组求和岂不是更快,而且编程复杂度又小,于是把之前写的删掉,写树状数组,写完模版之后忽然发现这题竟然是区间修改!

于是又删掉重写,忽然发现不会处理又加又乘的,果断看题解……

经过几乎两个小时的调试,终于1A。

需要注意的是,一定要让线段树的每一个区间保存的值时刻为正确的,这样才能在调用时直接返回。比如说这道题的change和query操作的最后一句话:

sum:=f(g[k<<1]+g[k<<1+1])

而不是

sum:=f(t[k<<1].sum+t[k<<1+1].sum)

时刻记住这点就ok了。一开始我还以为我的模版记错了呢……

代码:

  1. type node=record
  2. l,r,ti,ad,sum:int64;
  3. end;
  4. var i,n,m,tagtime,tagadd,ch,x,y,c,p:longint;
  5. t:array[..] of node;
  6. function f(x:int64):int64;
  7. begin
  8. f:=x mod p;
  9. end;
  10. function g(k:longint):longint;
  11. begin
  12. with t[k] do
  13. begin
  14. g:=f(f(sum*ti)+f(ad*(r-l+)));
  15. end;
  16. end;
  17. procedure build(x,y,k:longint);
  18. var mid:longint;
  19. begin
  20. with t[k] do
  21. begin
  22. l:=x;r:=y;ad:=;ti:=;
  23. if l=r then begin read(sum);sum:=f(sum);exit;end;
  24. mid:=(l+r)>>;
  25. build(l,mid,k<<);
  26. build(mid+,r,k<<+);
  27. sum:=f(t[k<<].sum+t[k<<+].sum);
  28. end;
  29. end;
  30. procedure pushdown(k:longint);
  31. begin
  32. with t[k] do
  33. begin
  34. if ti<> then
  35. begin
  36. sum:=f(sum*ti);
  37. t[k<<].ti:=f(t[k<<].ti*ti);
  38. t[k<<].ad:=f(t[k<<].ad*ti);
  39. t[k<<+].ti:=f(t[k<<+].ti*ti);
  40. t[k<<+].ad:=f(t[k<<+].ad*ti);
  41. ti:=;
  42. end;
  43. if ad<> then
  44. begin
  45. sum:=f(sum+ad*(r-l+));
  46. t[k<<].ad:=f(t[k<<].ad+ad);
  47. t[k<<+].ad:=f(t[k<<+].ad+ad);
  48. ad:=;
  49. end;
  50. end;
  51. end;
  52. procedure change(x,y,k:longint);
  53. var mid:longint;
  54. begin
  55. with t[k] do
  56. begin
  57. if (l=x) and (r=y) then
  58. begin
  59. ti:=(ti*tagtime) mod p;
  60. ad:=(ad*tagtime+tagadd) mod p;
  61. exit;
  62. end;
  63. pushdown(k);
  64. mid:=(l+r)>>;
  65. if y<=mid then change(x,y,k<<)
  66. else if x>mid then change(x,y,k<<+)
  67. else
  68. begin
  69. change(x,mid,k<<);
  70. change(mid+,y,k<<+);
  71. end;
  72. sum:=f(g(k<<)+g(k<<+));
  73. end;
  74. end;
  75. function query(x,y,k:longint):longint;
  76. var mid:longint;
  77. begin
  78. with t[k] do
  79. begin
  80. pushdown(k);
  81. if (l=x) and (r=y) then exit(f(sum));
  82. mid:=(l+r)>>;
  83. if y<=mid then query:=f(query(x,y,k<<))
  84. else if x>mid then query:=f(query(x,y,k<<+))
  85. else query:=f(f(query(x,mid,k<<))+f(query(mid+,y,k<<+)));
  86. sum:=f(g(k<<)+g(k<<+));
  87. end;
  88. end;
  89. procedure init;
  90. begin
  91. readln(n,p);
  92. build(,n,);
  93. end;
  94. procedure main;
  95. begin
  96. readln(m);
  97. for i:= to m do
  98. begin
  99. read(ch);
  100. if ch= then
  101. begin
  102. readln(x,y,tagtime);
  103. tagadd:=;
  104. change(x,y,);
  105. end
  106. else if ch= then
  107. begin
  108. readln(x,y,tagadd);
  109. tagtime:=;
  110. change(x,y,);
  111. end
  112. else
  113. begin
  114. readln(x,y);
  115. writeln(query(x,y,));
  116. end;
  117. end;
  118. end;
  119. begin
  120. init;
  121. main;
  122. end.

虽然现在已经12:30了,但我感觉,很开心。做了这道题,值!

bzoj1789 AHOI 维护数列(线段树)的更多相关文章

  1. [AHOI2009]维护序列 (线段树)

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  2. [P2023][AHOI2009]维护序列(线段树)

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  3. BZOJ1798[Ahoi2009]维护序列——线段树

    题目描述     老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成.    有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2 ...

  4. 【AHOI2009】 维护序列 - 线段树

    题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一 ...

  5. Codeforces 446C - DZY Loves Fibonacci Numbers(斐波那契数列+线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 你可能会疑惑我为什么要写 *2400 的题的题解 首先一个很明显的想法是,看到斐波那契数列和 \(10^9+9\) 就想到通项公式,\(F ...

  6. BZOJ.5286.[AHOI/HNOI2018]转盘(线段树)

    BZOJ LOJ 洛谷 如果从\(1\)开始,把每个时间\(t_i\)减去\(i\),答案取决于\(\max\{t_i-i\}\).记取得最大值的位置是\(p\),答案是\(t_p+1+n-1-p=\ ...

  7. BZOJ 1798 AHOI2009 Seq 维护序列 线段树

    题目大意:维护一个序列,提供三种操作: 1.将区间中每个点的权值乘上一个数 2.将区间中每个点的权值加上一个数 3.求一段区间的和对p取模的值 2631的超^n级弱化版.写2631之前能够拿这个练练手 ...

  8. P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA

    \(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...

  9. P1438 无聊的数列 (线段树)

    题目链接 Solution 直接维护一个差分的线段树就好了. 其中线段树的节点代表 \(r\) 比 \(l\) 多多少. Code #include<bits/stdc++.h> #def ...

随机推荐

  1. Spark小课堂Week3 FirstSparkApp(RDD开发)

    Spark小课堂Week3 FirstSparkApp 问题:Java有哪些数据结构 大致有如下几种,其中List与Map是最重要的: List Map Set Array Heap Stack Qu ...

  2. LeetCode之Single Number以及拓展

    Problem 1:一个数组中有一个数字a只出现一次,其他数字都出现了两次.请找出这个只出现一次的数字? 考察知识点:异或运算 思路:比如数字 b^b = 0     a^0 = a 因此,可以将数组 ...

  3. Linux多进行之fork

    #include <unistd.h> //定义该函数 #include <sys/types.h> //定义函数的返回类型pid_t /* 功能:复制进程 参数:无 返回值: ...

  4. C语言控制语句总结(if else for switch while break continue)

    一.if语句 1表达式 if(条件表达式) 语句 注: (1)条件表达式,一般为逻辑表达式或关系表达式,但也可以是任何数值类型,如整型.实型.字符型.指针型数据等. (2)语句,由于是C语言的语句,而 ...

  5. Speech Patterns (string)

    People often have a preference among synonyms of the same word. For example, some may prefer "t ...

  6. Torry的困惑(基本型)

    #include<stdio.h> int main() { long long i,j; int n; //用于记录输入的要进行乘积的质数的个数 ; //用于记录前n个质数的乘积,并初始 ...

  7. Hibernate从入门到精通(五)一对一单向关联映射

    上次的博文中Hibernate从入门到精通(四)基本映射我们已经讲解了一下基本映射和相关概念,接下来我们会讲稍微复杂点的映射——关系映射. 关系映射分类 关系映射即在基本映射的基础上处理多个相关对象和 ...

  8. python logging 日志轮转文件不删除问题

    前言 最近在维护项目的python项目代码,项目使用了 python 的日志模块 logging, 设定了保存的日志数目, 不过没有生效,还要通过contab定时清理数据. 分析 项目使用了 logg ...

  9. mybatis generator自动生成 实体类, sqlmap配置文件 详细介绍

    我使用的是Eclipse Luna 装了自己常用的插件, generator也是其中一个推荐下载 MyBatis_Generator_1.3.1.zip离线安装包 <?xml version=& ...

  10. C# Windows - ListBox&CheckedListBox

    ListBox和CheckedListBox类的属性 属性 说明 SelectedIndex 这个值表明列表框中选中项的基于0的索引 ColumnWidth 在包含多个列的列表框中,这个属性指定列宽 ...