bzoj 4303 数列

  • 二维 \(KD-Tree\) 模板题.
  • \(KD-Tree\) 虽然在更新和查询的方式上类似于线段树,但其本身定义是类似于用 \(splay/fhq\ treap\) 维护区间的二叉搜索树,没有加点删点,建树时将它建成平衡的就好了.
  • 这使得一个 \(node\) 的左子树管辖 \([l,mid-1]\) ,右子树管辖 \([mid+1,r]\) , \(mid\) 处的信息存在自己处,不要写混.
  • 对于 \(k\) 维的 \(KD-Tree\) ,它每次更新/查询的时间复杂度是 \(O(n^{1-\frac 1 k})\) .所以本题总时间复杂度为 \(O(m\sqrt n)\).
  • 在常数优化上有一个小技巧:若答案 \(ans\) 对 \(2^k\) 取模,可以直接输出 $ans&(P-1) $.本题 \(536870912=2^{29}\).
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define mp make_pair
  5. #define pii pair<int,int>
  6. #define inf 0x7f7f7f7f
  7. inline int read()
  8. {
  9. int x=0;
  10. bool pos=1;
  11. char ch=getchar();
  12. for(;!isdigit(ch);ch=getchar())
  13. if(ch=='-')
  14. pos=0;
  15. for(;isdigit(ch);ch=getchar())
  16. x=x*10+ch-'0';
  17. return pos?x:-x;
  18. }
  19. const int MAXN=5e4+10;
  20. const int P=536870912;
  21. inline int add(int a,int b)
  22. {
  23. return (a + b) ;
  24. }
  25. inline int mul(int a,int b)
  26. {
  27. return a * b ;
  28. }
  29. int n,m,Tp;
  30. struct node{
  31. int tp;//维护的维度
  32. int mi[2],ma[2];//[x/y]的最小,最大值
  33. int v[2];//坐标
  34. int ls,rs;
  35. int tagadd,tagmul;
  36. int val,len,sum;
  37. bool operator < (const node& rhs) const
  38. {
  39. return v[Tp]<rhs.v[Tp];//当前比较的维度,全局变量储存.
  40. }
  41. node()
  42. {
  43. ls=rs=0;
  44. tagadd=0;
  45. tagmul=1;
  46. sum=0;
  47. }
  48. }Tree[MAXN];
  49. #define root Tree[o]
  50. #define lson Tree[Tree[o].ls]
  51. #define rson Tree[Tree[o].rs]
  52. void pushup(int o)
  53. {
  54. root.mi[0]=min(root.v[0],min(lson.mi[0],rson.mi[0]));
  55. root.mi[1]=min(root.v[1],min(lson.mi[1],rson.mi[1]));
  56. root.ma[0]=max(root.v[0],max(lson.ma[0],rson.ma[0]));
  57. root.ma[1]=max(root.v[1],max(lson.ma[1],rson.ma[1]));
  58. }
  59. int BuildTree(int l,int r,int tp)
  60. {
  61. Tp=tp;
  62. int mid=(l+r)>>1;
  63. int o=mid;
  64. nth_element(Tree+l,Tree+mid,Tree+r+1);
  65. root.tp=tp;
  66. root.len=r-l+1;
  67. if(l<mid)
  68. root.ls=BuildTree(l,mid-1,(tp+1)%2);
  69. if(r>mid)
  70. root.rs=BuildTree(mid+1,r,(tp+1)%2);
  71. pushup(o);
  72. return o;
  73. }
  74. void Modifiy_mul(int o,int mulv)
  75. {
  76. root.val=mul(root.val,mulv);
  77. root.tagmul=mul(root.tagmul,mulv);
  78. root.tagadd=mul(root.tagadd,mulv);
  79. root.sum=mul(root.sum,mulv);
  80. }
  81. void Modifiy_add(int o,int addv)
  82. {
  83. root.val=add(root.val,addv);
  84. root.tagadd=add(root.tagadd,addv);
  85. root.sum=add(root.sum,mul(root.len,addv));
  86. }
  87. void pushdown(int o)
  88. {
  89. if(root.tagmul!=1)
  90. {
  91. Modifiy_mul(root.ls,root.tagmul);
  92. Modifiy_mul(root.rs,root.tagmul);
  93. root.tagmul=1;
  94. }
  95. if(root.tagadd!=0)
  96. {
  97. Modifiy_add(root.ls,root.tagadd);
  98. Modifiy_add(root.rs,root.tagadd);
  99. root.tagadd=0;
  100. }
  101. }
  102. void update(int o,int L,int R,int mulv,int addv)//修改第Tp维
  103. {
  104. if(L>root.ma[Tp] || R<root.mi[Tp])
  105. return;
  106. if(L<=root.mi[Tp] && root.ma[Tp]<=R)
  107. {
  108. Modifiy_mul(o,mulv);
  109. Modifiy_add(o,addv);
  110. return;
  111. }
  112. pushdown(o);
  113. if(L<=root.v[Tp] && root.v[Tp]<=R)
  114. {
  115. root.val=mul(root.val,mulv);
  116. root.val=add(root.val,addv);
  117. }
  118. pushdown(o);
  119. update(root.ls,L,R,mulv,addv);
  120. update(root.rs,L,R,mulv,addv);
  121. root.sum=add(lson.sum,rson.sum);
  122. root.sum=add(root.sum,root.val);
  123. }
  124. int query(int o,int L,int R)
  125. {
  126. if(L>root.ma[Tp] || R<root.mi[Tp])
  127. return 0;
  128. if(L<=root.mi[Tp] && root.ma[Tp]<=R)
  129. return root.sum;
  130. pushdown(o);
  131. int res=0;
  132. if(root.ls)
  133. res=add(res,query(root.ls,L,R));
  134. if(root.rs)
  135. res=add(res,query(root.rs,L,R));
  136. if(L<=root.v[Tp] && root.v[Tp]<=R)
  137. res=add(res,root.val);
  138. return res;
  139. }
  140. int rt;
  141. void init()
  142. {
  143. Tree[0].ma[0]=Tree[0].ma[1]=-inf;
  144. Tree[0].mi[0]=Tree[0].mi[1]=inf;
  145. for(int i=1;i<=n;++i)
  146. {
  147. Tree[i].v[0]=i;
  148. Tree[i].v[1]=read();
  149. }
  150. rt=BuildTree(1,n,0);
  151. }
  152. int main()
  153. {
  154. n=read(),m=read();
  155. init();
  156. while(m--)
  157. {
  158. int op=read();
  159. int l,r,x,y;
  160. if(op==0)
  161. {
  162. l=read(),r=read(),x=read(),y=read();
  163. Tp=0;
  164. update(rt,l,r,x,y);
  165. }
  166. else if(op==1)
  167. {
  168. l=read(),r=read(),x=read(),y=read();
  169. Tp=1;
  170. update(rt,l,r,x,y);
  171. }
  172. else if(op==2)
  173. {
  174. l=read(),r=read();
  175. Tp=0;
  176. printf("%d\n",query(rt,l,r)&(P-1));
  177. }
  178. else
  179. {
  180. l=read(),r=read();
  181. Tp=1;
  182. printf("%d\n",query(rt,l,r)&(P-1));
  183. }
  184. }
  185. return 0;
  186. }

bzoj 4303 数列的更多相关文章

  1. [BZOJ 2989]数列(二进制分组+主席树)

    [BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...

  2. [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)

    [BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...

  3. BZOJ 3142 数列(组合)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3142 题意:给出n,K,m,p.求有多少长度为K的序列A,满足:(1)首项为正整数:(2 ...

  4. BZOJ 4305: 数列的GCD( 数论 )

    对于d, 记{ai}中是d的倍数的数的个数为c, 那么有: 直接计算即可,复杂度O(NlogN+MlogM) --------------------------------------------- ...

  5. bzoj 4305 数列的GCD

    LINK:数列的GCD 题意: 给出一个长度为N的数列{a[n]},1<=a[i]<=M(1<=i<=N). 现在问题是,对于1到M的每个整数d,有多少个不同的数列b[1], ...

  6. bzoj 2989: 数列

    LINK:数列 需要动一点脑子 考虑查询 暴力显然不行 考虑把绝对值拆开. 当x<=y ax<=ay时 有 y-x+ay-ax<=k x+ax>=y+ay-k 可以发现在满足前 ...

  7. BZOJ 2989: 数列/4170: 极光

    题解: n倍经验题 首先比较容易想到的是对绝对值分类讨论 然后是4维偏序 1.查询和修改顺序 2.x>y 3.a[x]>a[y] 4.(x+a[x])-(y+a[y])<=k 这样是 ...

  8. 解题:BZOJ 2989 数列

    题面 学习二进制分组 题目本身可以看成二维平面上的问题,转成切比雪夫距离后就是矩形和了 二进制分组是将每个修改添加到末尾,然后从后往前二进制下进位合并,这样最多同时有$\log n$组,每个修改只会被 ...

  9. BZOJ #2989. 数列 [树套树]

    考虑转化问题模型,这个没必要可持久化,直接加点就可以了,还不用删点 每次的问题是求 曼哈顿距离,变成切比雪夫距离然后求解 然后我们考虑将这玩意旋转 45度, 然后原坐标的 \((x,y)\) 会变成 ...

随机推荐

  1. Markdown锚点使用

    为了使得博客看起来更加美观,我更倾向于使用索引,但是如何在Markdown使用索引跳到指定位置呢?以下是使用方法: 具体应用场景: (1)文献列表中链接--可以通过锚实现页面内的链接:引用文献中可能需 ...

  2. linux 用 grep 查找单个或多个字符串(关键字)

    1.单个 cat /tmp/php.log | grep "成功" 所有的成功都会被查询出来. 2.多个,并列查询 cat /tmp/php.log | grep "推荐 ...

  3. gcc,gdb,make学习

    实例学习gcc+gdb+make程序编译.链接.运行时头文件或动态链接库的查找 分四步: 预处理.编译.汇编.链接4steps:preprocess,compile,assemble,link ​

  4. 【Python】简单实现爬取小说《天龙八部》,并在页面本地访问

    背景 很多人说学习爬虫是提升自己的一个非常好的方法,所以有了第一次使用爬虫,水平有限,依葫芦画瓢,主要作为学习的记录. 思路 使用python的requests模块获取页面信息 通过re模块(正则表达 ...

  5. guava的事件发布订阅功能

    事件的重要性,不用说很重要,在很多时候我们做完一个操作的时候,需要告知另外一个对象让他执行相应操作,比如当用户注册成功的时候,需要抛出一个注册成功的事件,那么有监听器捕获到这个事件,完成后续用户信息初 ...

  6. (1) iOS开发之UI处理-预览篇

    不管是做iOS还是Android的开发,我想UI这块都是个大麻烦,任何客户端编程都是如此,我们要做的就是尽量减少我们工作的复杂度,这样才能更轻松的工作. 在iOS开发中Xcode虽然自带了强大的IB( ...

  7. IOS-CocoaPods制作篇

    作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/20067595 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关 ...

  8. Linux 系统启动过程,Linux 系统目录结构

    一.Linux 系统启动过程 linux启动时我们会看到许多启动信息. Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立 ...

  9. golang简易版聊天室

    功能需求: 创建一个聊天室,实现群聊和单聊的功能,直接输入为群聊,@某人后输入为单聊 效果图: 群聊:   单聊: 服务端: package main import ( "fmt" ...

  10. SpringCloud_00_资源帖

    一.官方资料 spring-cloud reference springcloud中文网 Spring Cloud 官方中文文档(dalston) 二.精选资料 1.翟永超-<Spring Cl ...