bzoj2989 数列(KDTree)

bzoj

该说不愧是咱,一个月才水一篇题解然后还水的一批

题目描述:

给定一个长度为n的正整数数列a[i]。
定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|。
2种操作(k都是正整数):
1.Modify x k:将第x个数的值修改为k。
2.Query x k:询问有几个i满足graze(x,i)<=k。因为可持久化数据结构的流行,询问不仅要考虑当前数列,还要
考虑任意历史版本,即统计任意位置上出现过的任意数值与当前的a[x]的graze值<=k的对数。(某位置多次修改为
同样的数值,按多次统计)

题解时间:

题目描述等效于先给出n个点之后操作为加一个新点或查询一个斜正方形内的点数

但是如果用kdt查斜正方形的话时间复杂度有被卡的风险。

所以旋转一下坐标系(旋转后的坐标系长什么样都行)

然后就变成查一个正方形了

插点的操作用替罪羊树暴力重构就好。

  1 #include<cstdio>
2 #include<algorithm>
3 const int N=100011;
4 using std::max;
5 using std::min;
6 using std::nth_element;
7 template<typename TP>
8 inline void read(TP &_t)
9 {
10 TP _r=0,_f=1;char _c=getchar();
11 while(_c<'0'||_c>'9'){if(_c=='-')_f=-1;_c=getchar();}
12 while(_c>='0'&&_c<='9'){_r=_r*10+_c-'0';_c=getchar();}
13 _t=_r*_f;
14 }
15 int n,T;
16 struct poi
17 {
18 int x[2];
19 poi(){}
20 poi(int a,int b){x[0]=a,x[1]=b;}
21 };
22 int DD;
23 int rt;
24 int lbx,lby,rtx,rty;
25 struct shion
26 {
27 int son[2],x[2],ma[2],mi[2],size,id;
28 }p[N];
29 int pi;
30 bool cmp(int a,int b){return p[a].x[DD]==p[b].x[DD]?p[a].x[!DD]<p[b].x[!DD]:p[a].x[DD]<p[b].x[DD];}
31
32 bool unbalance;
33 int ud,ux,*uf;
34 void fuckup(int px)
35 {
36 p[px].size=1+p[p[px].son[0]].size+p[p[px].son[1]].size;
37 p[px].ma[0]=p[px].mi[0]=p[px].x[0];
38 p[px].ma[1]=p[px].mi[1]=p[px].x[1];
39 for(int i=0;i<2;i++)
40 if(p[px].son[i])
41 for(int j=0;j<2;j++)
42 {
43 p[px].ma[j]=max(p[px].ma[j],p[p[px].son[i]].ma[j]);
44 p[px].mi[j]=min(p[px].mi[j],p[p[px].son[i]].mi[j]);
45 }
46 }
47 void insert(int &px,poi a,int dim,int f=0)
48 {
49 if(!px)
50 {
51 px=++pi;
52 p[pi].x[0]=a.x[0],p[pi].x[1]=a.x[1];
53 fuckup(px);
54 return;
55 }
56 if(a.x[dim]<=p[px].x[dim]) insert(p[px].son[0],a,dim^1,px);
57 else insert(p[px].son[1],a,dim^1,px);
58 fuckup(px);
59 if(p[px].son[0]&&p[p[px].son[0]].size*100>p[px].size*70)
60 ux=px,uf=(f?(&p[f].son[p[f].son[1]==px]):(&rt)),unbalance=1,ud=dim;
61 if(p[px].son[1]&&p[p[px].son[1]].size*100>p[px].size*70)
62 ux=px,uf=(f?(&p[f].son[p[f].son[1]==px]):(&rt)),unbalance=1,ud=dim;
63 }
64 void rebuild();
65 void insert(poi a)
66 {
67 insert(rt,a,0);
68 if(unbalance) rebuild();
69 }
70 int ul[N],uli;
71 void dfs(int px)
72 {
73 if(!px) return;
74 dfs(p[px].son[0]);
75 ul[++uli]=px;
76 dfs(p[px].son[1]);
77 p[px].son[0]=p[px].son[1]=0;
78 }
79 void build(int &px,int l,int r,int dim)
80 {
81 if(l==r)
82 {
83 px=ul[l];
84 fuckup(px);
85 return;
86 }
87 DD=dim;
88 int pm=l+r>>1;
89 nth_element(ul+l,ul+pm,ul+r+1,cmp);
90 px=ul[pm];
91 if(l<pm) build(p[px].son[0],l,pm-1,dim^1);
92 if(r>pm) build(p[px].son[1],pm+1,r,dim^1);
93 fuckup(px);
94 }
95 void rebuild()
96 {
97 uli=0;
98 dfs(ux);
99 *uf=0;
100 build(*uf,1,uli,ud);
101 unbalance=0;
102 }
103 int check(int px)
104 {
105 if(p[px].ma[0]<lbx||p[px].mi[0]>rtx||p[px].ma[1]<lby||p[px].mi[1]>rty) return -1;
106 if(lbx<=p[px].mi[0]&&p[px].ma[0]<=rtx&&lby<=p[px].mi[1]&&p[px].ma[1]<=rty) return 1;
107 return 0;
108 }
109 int query(int px)
110 {
111 if(!px) return 0;
112 int pas=check(px);
113 switch(pas)
114 {
115 case -1:{
116 return 0;
117 break;
118 }
119 case 0:{
120 return query(p[px].son[0])+query(p[px].son[1])+(lbx<=p[px].x[0]&&p[px].x[0]<=rtx&&lby<=p[px].x[1]&&p[px].x[1]<=rty);
121 break;
122 }
123 case 1:{
124 return p[px].size;
125 break;
126 }
127 }
128 }
129 int a[N];
130
131 int xi,yi;
132 char op[5];
133 int main()
134 {
135 for(int i=1;i<=100000;i++) p[i].id=i;
136 read(n),read(T);
137 for(int i=1;i<=n;i++) read(a[i]),
138 insert(poi(i+a[i],i-a[i]));
139 while(T--)
140 {
141 scanf("%s",op);
142 switch(op[0])
143 {
144 case 'M':
145 {
146 read(xi),read(yi);
147 insert(poi(xi+yi,xi-yi));
148 a[xi]=yi;
149 break;
150 }
151 case 'Q':
152 {
153 read(xi),read(yi);
154 lbx=xi+a[xi]-yi,lby=xi-a[xi]-yi;
155 rtx=xi+a[xi]+yi,rty=xi-a[xi]+yi;
156 printf("%d\n",query(rt));
157 break;
158 }
159 }
160 }
161 return 0;
162 }

(数据删除)被数据结构的装腔作势激怒了

bzoj2989 数列(KDTree)的更多相关文章

  1. 【BZOJ2989】数列 kd-tree

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

  2. 【bzoj2989】数列 KD-tree+旋转坐标系

    题目描述 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|. 2种操作(k都是正整数): 1.Mo ...

  3. [bzoj2989]数列_KD-Tree_旋转坐标系

    数列 bzoj-2989 题目大意:题目链接. 注释:略. 想法:显然,我们用x和a[x]两个值建立笛卡尔坐标系. 两个点之间的距离为曼哈顿距离. 修改操作就是插入... 查询操作就是查询一个点周围的 ...

  4. BZOJ2989 数列(二进制分组)

    这题其实可以cdq分治做,但是如果强制在线的话,这里有个牛逼方法叫二进制分组. 它的基本思想是把修改操作按二进制分组,遇到修改就在尾部加一个,并与之前的合并,比如之前有23(16+4+2+1)个,加了 ...

  5. 2019.01.21 bzoj2989: 数列(二进制分组+主席树)

    传送门 二进制分组入门题. 主席树写错调题2h+2h+2h+体验极差. 题意简述:给一堆点,支持加入一个点,询问有多少个点跟(x,y)(x,y)(x,y)曼哈顿距离不超过kkk. 思路:题目要求的是对 ...

  6. bzoj2989 数列

    突然翻到一道他们正在做的题....好像是cdq分治??? 以后写写呗.... 然后二进制啥的照样操作一波....感觉很资瓷的样子.... 就这样分组操作两边这道题咯?

  7. Kd-tree题表

    bzoj1941: [Sdoi2010]Hide and Seekbzoj2626: JZPFARbzoj4520: [Cqoi2016]K远点对bzoj2989: 数列bzoj2850: 巧克力王国 ...

  8. 【BZOJ2989】数列(二进制分组,主席树)

    [BZOJ2989]数列(二进制分组,主席树) 题面 BZOJ 权限题啊... Description 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即g ...

  9. 【BZOJ2989】数列(CDQ分治,扫描线)

    [BZOJ2989]数列(CDQ分治) 题面 BZOJ 权.....权限题.. 题解 Description 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和 ...

随机推荐

  1. Note -「矩阵树定理」学习笔记

      大概--会很简洁吧 qwq. 矩阵树定理   对于无自环无向图 \(G=(V,E)\),令其度数矩阵 \(D\),邻接矩阵 \(A\),令该图的 \(\text{Kirchhoff}\) 矩阵 \ ...

  2. Linux性能优化之磁盘I/O性能指标

    讨论指标之前,得先解决两个概念:文件系统和磁盘I/O栈. 文件系统是什么?文件系统是在磁盘的基础上,提供了一个用来管理文件的树状结构.简言之,文件系统是树状结构,一种数据结构~逻辑上的概念.磁盘大家都 ...

  3. 大厂偏爱的Agent技术究竟是个啥

    搜索关注微信公众号"捉虫大师",后端技术分享,架构设计.性能优化.源码阅读.问题排查.踩坑实践. hello大家好,我是小楼,今天给大家分享一个关于Agent技术的话题,也是后端启 ...

  4. 【程序员的实用工具推荐】 Mac 效率神器 Alfred

    Alfred 是一款功能非常强大,能有效提升 Mac 电脑使用效率的神器.可以说有了 Alfred 你就基本上可以脱离鼠标实现各种操作.相比 Mac 自带的聚焦搜索,完全可以称得上拥有碾压性的优势. ...

  5. 开源绘画应用 Pinta 已移植到GTK 3和.NET 6

    Pinta 是一款开源绘画应用,适用于 Linux.Windows 和 macOS.你可以用它来进行自由手绘/素描.你也可以用它在现有的图片上添加箭头.方框.文字等. 年初发布了 Pinta 2.0. ...

  6. 【C# TAP 异步编程】四、SynchronizationContext 同步上下文|ExecutionContext

    一.同步上下文(SynchronizationContext)概述 由来 多线程程序在.net框架出现之前就已经存在了.这些程序通常需要一个线程将一个工作单元传递给另一个线程.Windows程序以消息 ...

  7. Typora简单使用

    Typora介绍 Typora是一款轻量级的Markdown编辑器,它没有采用传统编辑器那样源代码和预览双栏显示的方式,让你所见即所得,能够及时预览.目前Typora在IT领域的人气极高,这也致使原来 ...

  8. Spring MVC视图解析器(ViewResolver)

    视图解析器(ViewResolver)是 Spring MVC 的重要组成部分,负责将逻辑视图名解析为具体的视图对象.Spring MVC 提供了很多视图解析类,其中每一项都对应 Java Web 应 ...

  9. 自己创建bmp图像

    随便找一张图片,右键选择打开方式为画图,再在画图中保存为bmp即可 如果要保存为png文件,也可以这样

  10. 初识——HTTP3

    目录 初识--HTTP3 HTTP HTTP1.0和HTTP1.1的主要区别 HTTP2 HTTP3 相关链接 初识--HTTP3 想了解HTTP3??那我们就得先知道为啥会出现HTTP3,因此我们需 ...