[BZOJ]4605 崂山白花蛇草水 线段树套KD-Tree
4605: 崂山白花蛇草水
Time Limit: 80 Sec Memory Limit: 512 MB
Submit: 527 Solved: 153
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1 1 1 1
1 2 2 3
1 4 1 2
1 3 4 4
2 1 1 4 1 3
2 2 2 3 5 4
2 2 1 4 4 2
Sample Output
NAIVE!ORZzyz.
3
HINT
Source
Idea By Aleph, Description & Data cases By jinlifu1999.
[Submit][Status][Discuss]
HOME Back
KD-Tree是个啥? 好像不会啊... 听说就是按维度来二分? 于是YY了一下, 没想到就还YY出来了KD-Tree嘿嘿。 建树的时候每次按一个维度来划分, 选中间那个点作为当前节点, 然后分开搞lson, rson... 树高显然log. 插入怎么维护树高... gg. 于是还是可耻的打开了学习笔记.
原来是用替罪羊暴力重建来, 妙啊妙啊, 不过秉承着自己平衡树只写数组的原则就放弃指针的写法了(线段树还是秉承丁神的指针... 所以这份代码又会有指针又会有数组...). 而且找中位数不用sort直接调用一个nth_element? 期望O(n)? 并不知道怎么做到的...
然后这道题就很水啦, 要找第k大外层套一个值域线段树即可, 内部套一个2d-tree维护矩阵即可. 第一次写学了Claris神犇的模板... 还是很好写的. 成功跟随神犇的脚步走上了第一页的光辉之路. 不过码量还是不小啊... 码力还是欠缺.
Ps:话说为什么找最早的替罪羊重建要跑60s, 找到第一个替罪羊重建就是10s? 记得论文说过有两种写法的啊(难不成记错了)... 说不定是我写丑了. 如果神犇有独特的见解希望能留言指导一下蒟蒻.
#include<bits/stdc++.h>
#define smax(x, y) x = max(x, y)
#define smin(x, y) x = min(x, y)
using namespace std;
const int inf = 1e9;
const int maxm = 3e5;
const double A = 0.75;
const int maxn = 1e6 + 7e5;
int deep, n, ans, cmpd, cnt, X1, X2, Y1, Y2, K, cur, type;
int tmp[maxm], re[maxm];
struct Seg_Node {int KDrt;Seg_Node *ls, *rs;
}pool[maxn], *root, *tail = pool;
struct KDT_Node {int ls, rs, siz;int d[2], Min[2], Max[2];
}t[maxn];
inline bool cmp(int x, int y) {return t[x].d[cmpd] < t[y].d[cmpd];
}
inline const int read() {register int x = 0;register char ch = getchar();while (ch < '0' || ch > '9') ch = getchar();while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();return x;
}
inline bool balance(int x) {return (double)t[t[x].ls].siz < A * t[x].siz && (double)t[t[x].rs].siz < A * t[x].siz;
}
inline void update(int x) {t[x].siz = t[t[x].ls].siz + t[t[x].rs].siz + 1;if (t[x].ls) {smax(t[x].Max[0], t[t[x].ls].Max[0]);smin(t[x].Min[0], t[t[x].ls].Min[0]);smax(t[x].Max[1], t[t[x].ls].Max[1]);smin(t[x].Min[1], t[t[x].ls].Min[1]);}if (t[x].rs) {smax(t[x].Max[0], t[t[x].rs].Max[0]);smin(t[x].Min[0], t[t[x].rs].Min[0]);smax(t[x].Max[1], t[t[x].rs].Max[1]);smin(t[x].Min[1], t[t[x].rs].Min[1]);}
}
void dfs(int x) {if (x)re[++ cnt] = x,dfs(t[x].ls), dfs(t[x].rs);
}
int build(int lf, int rg, int D) {int mid = (lf + rg) >> 1;cmpd = D;nth_element(re + lf + 1, re + mid + 1, re + rg + 1, cmp);int x = re[mid];t[x].Max[0] = t[x].Min[0] = t[x].d[0];t[x].Max[1] = t[x].Min[1] = t[x].d[1];if (lf ^ mid) t[x].ls = build(lf, mid - 1, !D);else t[x].ls = 0; if (rg ^ mid) t[x].rs = build(mid + 1, rg, !D);else t[x].rs = 0;update(x);return x;
}
inline void insert(int &rt, int now) {if (!rt) {rt = now;return;}for (int D = deep = 0, x = rt; ; D ^= 1) {tmp[++ deep] = x;t[x].siz ++;smax(t[x].Max[0], t[now].Max[0]);smin(t[x].Min[0], t[now].Min[0]);smax(t[x].Max[1], t[now].Max[1]);smin(t[x].Min[1], t[now].Min[1]);if (t[now].d[D] < t[x].d[D]) {if (!t[x].ls) {t[x].ls = now;break;} else x = t[x].ls;} else {if (!t[x].rs) {t[x].rs = now;break;} else x = t[x].rs;}}tmp[++ deep] = now;while (balance(now)) now = tmp[-- deep];if (!now) return;cnt = 0;if (now == rt) {dfs(rt);rt = build(1, cnt, 0);} else {dfs(now);int f = tmp[-- deep];int k = build(1, cnt, deep & 1);(t[f].ls == now) ? t[f].ls = k : t[f].rs = k;}
}
inline void ask(int x) {if (!x || t[x].Max[0] < X1 || t[x].Min[0] > X2 || t[x].Max[1] < Y1 || t[x].Min[1] > Y2 || ans >= K) return;if (t[x].Min[0] >= X1 && t[x].Max[0] <= X2&& t[x].Min[1] >= Y1 && t[x].Max[1] <= Y2) {ans += t[x].siz; return;}if (t[x].d[0] >= X1 && t[x].d[0] <= X2 && t[x].d[1] >= Y1 && t[x].d[1] <= Y2) ans ++;ask(t[x].ls), ask(t[x].rs);
}
inline void add() {Seg_Node *bt = root;int lf = 1, rg = inf, flag = 1;while(true) {if (flag) {cur ++;t[cur].siz = 1; t[cur].Max[0] = t[cur].Min[0] = t[cur].d[0] = X1;t[cur].Max[1] = t[cur].Min[1] = t[cur].d[1] = Y1;insert(bt -> KDrt, cur);}if (lf == rg) return;int mid = (lf + rg) >> 1;if (K <= mid) {if (bt -> ls == NULL) bt -> ls = ++ tail;bt = bt -> ls, rg = mid, flag = 0;} else {if (bt -> rs == NULL) bt -> rs = ++ tail;bt = bt -> rs, lf = mid + 1, flag = 1;}}
}
inline void seg_query() {ans = 0, ask(root -> KDrt);if (ans < K) {ans = 0;puts("NAIVE!ORZzyz.");return;}Seg_Node* bt = root;int lf = 1, rg = inf;while(lf < rg) {int mid = (lf + rg) >> 1;ans = 0;if (bt -> rs != NULL) ask(bt -> rs -> KDrt);if (ans >= K) bt = bt -> rs, lf = mid + 1; else bt = bt -> ls, rg = mid, K -= ans;}printf("%d\n", ans = lf);
}
int main() {root = ++ tail;n = read(), n = read();for (register int i = 1; i <= n; ++ i) {type = read();X1 = read(), Y1 = read();X1 ^= ans, Y1 ^= ans;if (type & 1) {K = read(), K ^= ans;add();} else {X2 = read(), Y2 = read(), K = read();X2 ^= ans, Y2 ^= ans, K ^= ans;seg_query();}}
}
[BZOJ]4605 崂山白花蛇草水 线段树套KD-Tree相关推荐
- BZOJ 4605: 崂山白花蛇草水 树套树 权值线段树套kdtree
4605: 崂山白花蛇草水 Time Limit: 80 Sec Memory Limit: 512 MB Submit: 527 Solved: 153 [Submit][Status][Dis ...
- BZOJ 4605 崂山白花蛇草水 权值线段树+K-D树
Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履行诺言的时 ...
- BZOJ 4605 崂山白花蛇草水(权值线段树+KD树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4605 [题目大意] 操作 1 x y k 表示在点(x,y)上放置k个物品, 操作 2 ...
- bzoj 4605 崂山白花蛇草水
http://www.elijahqi.win/archives/3722 Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水. ...
- 【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树
外层是借鉴了kd-tree的替罪羊里层是线段树,插入就是正常插入+拍扁重建,查询的时候,我们就像树状数组套线段树一样操作在替罪羊中找到的线段树根节点,但是对于在kd-tree查找过程中遇到的单点,我们 ...
- bzoj4605 崂山白花蛇草水 权值线段树套kd树
Description Q次操作,要求资瓷 在(x,y)处放一个数字x 查询(x1,y1)到(x2,y2)矩形内第k大 Solution 非常裸的权值线段树套kd树,为了保证复杂度可以定期重构也可以平 ...
- 【线段树套KD树】[BZOJ4605]崂山白花蛇草水
题目描述 Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履 ...
- bzoj4605: 崂山白花蛇草水 //替罪羊式重构k-d树
bzoj4605: 崂山白花蛇草水 题意 Q(<=100000)次操作,支持: 在二维平面上插入一个坐标(x,y)(x,y<=500000),点权为v(<=1e9)的点: 查询矩形区 ...
- BZOJ4605:崂山白花蛇草水
浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...
最新文章
- 如何使用 FFmpeg 减小视频大小
- ArcGIS实验教程——实验五:空间数据编辑
- 使用Kakapo.js进行动态模拟
- iis php mysql 集成_如何在IIS上集成php(iis+mysql+php+zend)
- 上下两个x轴_工业机器人到底有多少个“轴”?
- 自定义控件省市区:仿苹果级联菜单
- table中添加下拉框
- CROC-MBTU 2012, Elimination Round (ACM-ICPC) H DP题目
- 重心坐标到纹理映射(Texture Mapping)
- [Windows] Visio 图形怎么旋转到指定角度?
- 【游戏开发实战】使用Unity制作水果消消乐游戏教程(一):生成冰块阵列
- OSChina 周一乱弹 —— 达叔撸猫图还是满满的少女心
- (CVPR 2019) GSPN: Generative Shape Proposal Network for 3D Instance Segmentation in Point Cloud
- android x86_646,雷电模拟器4.0x86_64位版本即android 7.1 xposed安装
- XPO 的三篇介绍文章。
- [解读REST] 1.REST的起源
- 学计算机励志名言,程序员励志格言
- Windows上Emwin的使用
- 视觉标记定位aruco使用
- Android高斯模糊(毛玻璃效果)蒙层库