[BZOJ]4605 崂山白花蛇草水 线段树套KD-Tree
2017-12-04 19:03
218 查看
4605: 崂山白花蛇草水
Time Limit: 80 Sec Memory Limit: 512 MBSubmit: 527 Solved: 153
[Submit][Status][Discuss]
Description
神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水。凭借着神犇Aleph的实力,他轻松地进了山东省省队,现在便是他履行诺言的时候了。蒟蒻Bob特地为他准备了999,999,999,999,999,999
瓶崂山白花蛇草水,想要灌神犇Aleph。神犇Aleph求(跪着的)蒟蒻Bob不要灌他,由于神犇Aleph是神犇,蒟蒻Bo
b最终答应了他的请求,但蒟蒻Bob决定将计就计,也让神犇Aleph回答一些问题。具体说来,蒟蒻Bob会在一个宽敞
的广场上放置一些崂山白花蛇草水(可视为二维平面上的一些整点),然后询问神犇Aleph在矩形区域(x1, y1), (
x2, y2)(x1≤x2且y1≤y2,包括边界)中,崂山白花蛇草水瓶数第k多的是多少。为了避免麻烦,蒟蒻Bob不会在同
一个位置放置两次或两次以上的崂山白花蛇草水,但蒟蒻Bob想为难一下神犇Aleph,希望他能在每次询问时立刻回
答出答案。神犇Aleph不屑于做这种问题,所以把这个问题交给了你。
Input
输入的第一行为两个正整数N, Q,表示横纵坐标的范围和蒟蒻Bob的操作次数(包括放置次数和询问次数)。接下来Q行,每行代表蒟蒻Bob的一个操作,操作格式如下:
首先第一个数字type,表示操作种类。type=1表示放置,type=2表示询问。
若type=1,接下来会有三个正整数x, y, v,表示在坐标整点(x, y)放置v瓶崂山白花蛇草水。(1≤x, y≤N, 1≤v≤10^9)
若type=2,接下来会有五个正整数x1, y1, x2, y2, k,表示询问矩形区域(x1, y1), (x2, y2)中,崂山白花蛇草水瓶数第k多的是多少。
(1≤x1≤x2≤N,1≤y1≤y2≤N,1≤k≤Q)
为了体现程序的在线性,你需要将每次读入的数据(除了type值)都异或lastans,其中lastans表示上次询问的答
案。如果上次询问的答案为"NAIVE!ORZzyz."(见样例输出),则将lastans置为0。初始时的lastans为0。
初始时平面上不存在崂山白花蛇草水。
本题共有12组测试数据。对于所有的数据,N≤500,000。
Q的范围见下表:
测试点1-2 Q=1,000
测试点3-7 Q=50,000
测试点8-12 Q=100,000
Output
对于每个询问(type=2的操作),回答崂山白花蛇草水瓶数第k多的是多少。若不存在第k多的瓶数,请输出"NAIVE!ORZzyz."(输出不含双引号)。
Sample Input
10 71 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.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(); } } }
相关文章推荐
- [BZOJ4605]崂山白花蛇草水(主席树套kd-tree)
- bzoj 4358: permu (莫队+栈||KD-tree||莫队+线段树)
- [权值线段树套kd树 替罪羊式重构] BZOJ 4605 崂山白花蛇草水
- 【BZOJ4605】崂山白花蛇草水 权值线段树+kd-tree
- 【线段树套KD树】[BZOJ4605]崂山白花蛇草水
- 【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树
- [bzoj1941][kd-tree]Hide and Seek
- [BZOJ][KD-tree]2626: JZPFAR
- [bzoj][Cqoi2016]K远点对【堆】【KD-tree】
- kd-tree学习&&hdu2966&&bzoj2648
- BZOJ 4605: 崂山白花蛇草水 树套树 权值线段树套kdtree
- bzoj 3489: A simple rmq problem (KD-tree)
- [bzoj2989]数列_KD-Tree_旋转坐标系
- bzoj1941: [Sdoi2010]Hide and Seek KD-tree
- BZOJ 2648 SJY摆棋子(KD-Tree)
- [线段树 区间最值操作 模板 Segment tree Beats!] BZOJ 4695 最假女选手
- CF 19D, 线段树套set/KD-tree
- bzoj 4066: 简单题 kd-tree
- 【BZOJ2648】SYJ摆棋子 KD-Tree
- BZOJ1941: [Sdoi2010]Hide and Seek kdtree