bzoj2989 数列(KDTree)
bzoj2989 数列(KDTree)
该说不愧是咱,一个月才水一篇题解然后还水的一批
题目描述:
题解时间:
题目描述等效于先给出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)的更多相关文章
- 【BZOJ2989】数列 kd-tree
[BZOJ2989]数列 Description 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- 【bzoj2989】数列 KD-tree+旋转坐标系
题目描述 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|. 2种操作(k都是正整数): 1.Mo ...
- [bzoj2989]数列_KD-Tree_旋转坐标系
数列 bzoj-2989 题目大意:题目链接. 注释:略. 想法:显然,我们用x和a[x]两个值建立笛卡尔坐标系. 两个点之间的距离为曼哈顿距离. 修改操作就是插入... 查询操作就是查询一个点周围的 ...
- BZOJ2989 数列(二进制分组)
这题其实可以cdq分治做,但是如果强制在线的话,这里有个牛逼方法叫二进制分组. 它的基本思想是把修改操作按二进制分组,遇到修改就在尾部加一个,并与之前的合并,比如之前有23(16+4+2+1)个,加了 ...
- 2019.01.21 bzoj2989: 数列(二进制分组+主席树)
传送门 二进制分组入门题. 主席树写错调题2h+2h+2h+体验极差. 题意简述:给一堆点,支持加入一个点,询问有多少个点跟(x,y)(x,y)(x,y)曼哈顿距离不超过kkk. 思路:题目要求的是对 ...
- bzoj2989 数列
突然翻到一道他们正在做的题....好像是cdq分治??? 以后写写呗.... 然后二进制啥的照样操作一波....感觉很资瓷的样子.... 就这样分组操作两边这道题咯?
- Kd-tree题表
bzoj1941: [Sdoi2010]Hide and Seekbzoj2626: JZPFARbzoj4520: [Cqoi2016]K远点对bzoj2989: 数列bzoj2850: 巧克力王国 ...
- 【BZOJ2989】数列(二进制分组,主席树)
[BZOJ2989]数列(二进制分组,主席树) 题面 BZOJ 权限题啊... Description 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即g ...
- 【BZOJ2989】数列(CDQ分治,扫描线)
[BZOJ2989]数列(CDQ分治) 题面 BZOJ 权.....权限题.. 题解 Description 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和 ...
随机推荐
- Jetpack的ViewModel与LiveData
本文基于SDK 29 一.ViewModel与LiveData的作用: 1.viewModel: 数据共享,屏幕旋转不丢失数据,并且在Activity与Fragment之间共享数据. 2.LiveDa ...
- NVDA、争渡读屏语音开放API接口
什么是读屏软件? 读屏软件是一种专为视力障碍人士设计的,能够辅助视障人士操作计算机的工具,它可以将屏幕上显示的内容用语音朗读出来,这样视障人士就可以正常使用电脑了. 知名的屏幕阅读软件国内有争渡读屏. ...
- figlet 一个在linux生成字符串图案的玩具
figlet官网 figlet官方字体库 figlet字体样例 安装方法 centos/redhat/fedora 发行版 yum install -y figlet debian/ubuntu 发行 ...
- PRML 概率分布
本文地址:https://www.cnblogs.com/faranten/p/15917369.html 转载请注明作者与出处 1 二元变量 1.1 伯努利分布与二项分布 考虑一个最基本的试验: ...
- Spring Boot 启动特别慢的问题
Q:debug模式下代码编译没有问题,本来10 ms左右可以启动的项目,却耗时了3000多ms,why? A:删除项目中的断点,留几个要用的就行. 至于怎么一键删除所有断点,请自行搜索! 一度以为我的 ...
- [Golang]Go语言入门笔记
跟着尚硅谷B站视频记的笔记 入门 go 编译和运行源代码 go build 编译源代码,生成可执行文件 go build -o newName.exe name.go go run 直接编译运行代码 ...
- DoS泛洪测试与防御
实验目的 DoS泛洪测试与防御 实验内容 DoS泛洪测试与防御 实验环境描述 1. 学生机与实验室网络直连: 2. VPC1与实验室网络直连: 3. 学生机与VPC1物理链路连通: 实验步骤 学生登录 ...
- [Matlab]二维统计分析图实例
常见的二维统计分析图形: bar(x,y,选项) 条形图 stairs(x,y,选项) 阶梯图 stem(x,y,选项) 杆图 fill(x1,y1,选项1,x2,y2,选项2,--) 填充图 实例: ...
- 为什么说国产BI更适合国内企业?
就算国外BI发展迅速,产品更加完善成熟,但对国内的企业来说,使用起来难免"水土不服",何况还有服务对接过程中的繁琐程.今天就来讨论一下,国内BI和国外BI到底该怎么选择? 国外B ...
- Zookeeper应用场景和ZAB协议
Zookeeper应用场景 数据发布/订阅(配置中心) 我们平常的开发过程中,经常会碰到这样的需求:系统中需要一些通用的配置信息,如一些运行时的开关.前端需要展示的通知信息.数据库配置信息等等.这些需 ...