HDU 5126 stars KDTree
来源:互联网 发布:51网络论坛 编辑:程序博客网 时间:2024/06/10 17:28
stars
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 980 Accepted Submission(s): 311
Problem Description
John loves to see the sky. A day has Q times. Each time John will find a new star in the sky, or he wants to know how many stars between (x1,y1,z1) and (x2,y2,z2) .
Input
The first line contains a single integer T(1≤T≤10) (the data for Q>100 less than 6 cases),, indicating the number of test cases.
The first line contains an integerQ(1≤Q≤50000) ,indicating how many times in a day.
Next Q lines contain some integers, first input an integerA(1≤A≤2) .If A=1 then input 3 integers x, y and z, indicating a coordinate of one star.. If A=2 then input 6 integers x1,y1,z1,x2,y2,z2(1≤x,y,z,x1,y1,z1,x2,y2,z2≤109,x1≤x2,y1≤y2,z1≤z2) .
The first line contains an integer
Next Q lines contain some integers, first input an integer
Output
For each “A=2”,output an integer means how many stars in such a section.
Sample Input
2111 1 1 12 1 1 1 1 1 11 2 2 21 1 1 22 1 1 1 2 2 21 3 3 31 4 4 41 5 5 51 6 6 62 1 1 1 6 6 62 3 3 3 6 6 6111 1 1 12 1 1 1 1 1 11 2 2 21 1 1 22 1 1 1 2 2 21 3 3 31 4 4 41 5 5 51 6 6 62 1 1 1 6 6 62 3 3 3 6 6 6
Sample Output
13741374
KD树裸题,最开始想着先不重构KD树,交上去试试,如果超时了再改。结果一直WA,一直在找BUG都找不到,实在没办法就试着重构KD树,于是就每1000个节点重构一次KD树,直接A了,没想到明明超时OJ却判成WA。
#include <bits/stdc++.h>#define maxn 100010#define inf 0x7fffffffusing namespace std;int n, m, root, cmpd;struct data{ int l, r, d[3], mx[3], mn[3], sum, w; // sum:以此为根节点数目和 w:节点上数字 data() {} data(int a, int b, int c, int val) { l = r = 0; d[0] = mx[0] = mn[0] = a; d[1] = mx[1] = mn[1] = b; d[2] = mx[2] = mn[2] = c; w = sum = val; }} tr[maxn];void update(int x){ int l = tr[x].l, r = tr[x].r; if (l) // 维护以此为根的子树各个维度范围与节点数目和 { tr[x].mx[0] = max(tr[x].mx[0], tr[l].mx[0]); tr[x].mn[0] = min(tr[x].mn[0], tr[l].mn[0]); tr[x].mx[1] = max(tr[x].mx[1], tr[l].mx[1]); tr[x].mn[1] = min(tr[x].mn[1], tr[l].mn[1]); tr[x].mx[2] = max(tr[x].mx[2], tr[l].mx[2]); tr[x].mn[2] = min(tr[x].mn[2], tr[l].mn[2]); tr[x].sum += tr[l].sum; } if (r) { tr[x].mx[0] = max(tr[x].mx[0], tr[r].mx[0]); tr[x].mn[0] = min(tr[x].mn[0], tr[r].mn[0]); tr[x].mx[1] = max(tr[x].mx[1], tr[r].mx[1]); tr[x].mn[1] = min(tr[x].mn[1], tr[r].mn[1]); tr[x].mx[2] = max(tr[x].mx[2], tr[r].mx[2]); tr[x].mn[2] = min(tr[x].mn[2], tr[r].mn[2]); tr[x].sum += tr[r].sum; }}int cmp(data a, data b){ if (a.d[cmpd] == b.d[cmpd]) { if (a.d[(cmpd + 1) % 3] == b.d[(cmpd + 1) % 3]) { return a.d[(cmpd + 2) % 3] < b.d[(cmpd + 2) % 3]; } return a.d[(cmpd + 1) % 3] < b.d[(cmpd + 1) % 3]; } return a.d[cmpd] < b.d[cmpd];}int build(int l, int r, int d){ int mid = (l + r) >> 1; cmpd = d; //不对整体排序,只求第n小的元素并放在其位置上 nth_element(tr + l, tr + mid, tr + r + 1, cmp); tr[mid].mx[0] = tr[mid].mn[0] = tr[mid].d[0]; tr[mid].mx[1] = tr[mid].mn[1] = tr[mid].d[1]; tr[mid].mx[2] = tr[mid].mn[2] = tr[mid].d[2]; tr[mid].sum = tr[mid].w; tr[mid].l = 0; tr[mid].r = 0; if (l < mid) { tr[mid].l = build(l, mid - 1, (d + 1) % 3); } if (r > mid) { tr[mid].r = build(mid + 1, r, (d + 1) % 3); } update(mid); return mid;}void kdinsert(int now){ if (now == root) { return; } int D, p; D = 0; p = root; while (true) { //插入到P中,维护信息 if (tr[now].mx[0] > tr[p].mx[0]) { tr[p].mx[0] = tr[now].mx[0]; } if (tr[now].mx[1] > tr[p].mx[1]) { tr[p].mx[1] = tr[now].mx[1]; } if (tr[now].mx[2] > tr[p].mx[2]) { tr[p].mx[2] = tr[now].mx[2]; } if (tr[now].mn[0] < tr[p].mn[0]) { tr[p].mn[0] = tr[now].mn[0]; } if (tr[now].mn[1] < tr[p].mn[1]) { tr[p].mn[1] = tr[now].mn[1]; } if (tr[now].mn[2] < tr[p].mn[2]) { tr[p].mn[2] = tr[now].mn[2]; } tr[p].sum += tr[now].sum; if (tr[p].d[0] == tr[now].d[0] && tr[p].d[1] == tr[now].d[1] && tr[p].d[2] == tr[now].d[2]) //相等时只更新不插入 { tr[p].w += tr[now].w; m--; return; } if (tr[now].d[D] >= tr[p].d[D]) { if (tr[p].r == 0) { tr[p].r = now; return; } else { p = tr[p].r; } } else { if (tr[p].l == 0) { tr[p].l = now; return; } else { p = tr[p].l; } } D = (D + 1) % 3; }}int query(int now, int x1, int y1, int z1, int x2, int y2, int z2){ // 当前节点范围与查询矩形不相交 if (!now || tr[now].mx[0] < x1 || tr[now].mn[0] > x2 || tr[now].mx[1] < y1 || tr[now].mn[1] > y2 || tr[now].mx[2] < z1 || tr[now].mn[2] > z2) { return 0; } // 当前节点范围包含查询矩形 if (tr[now].mx[0] <= x2 && tr[now].mn[0] >= x1 && tr[now].mx[1] <= y2 && tr[now].mn[1] >= y1 && tr[now].mx[2] <= z2 && tr[now].mn[2] >= z1) { return tr[now].sum; } int ret = 0; // 查询矩形包含当前节点 if (tr[now].d[0] >= x1 && tr[now].d[0] <= x2 && tr[now].d[1] >= y1 && tr[now].d[1] <= y2 && tr[now].d[2] >= z1 && tr[now].d[2] <= z2) { ret += tr[now].w; } ret += query(tr[now].l, x1, y1, z1, x2, y2, z2) + query(tr[now].r, x1, y1, z1, x2, y2, z2); return ret;}int main(){#ifdef LOCAL freopen("data.in", "r", stdin); freopen("data.out", "w", stdout);#endif int t; scanf("%d", &t); while (t--) { scanf("%d", &n); int op; m = 0; int mod = 10000; root = 1; while (n--) { scanf("%d", &op); if (op == 1) { int x, y, z; scanf("%d %d %d", &x, &y, &z); tr[++m] = data(x, y, z, 1); kdinsert(m); if (m % mod == 0) //每mod次重建KD树 { root = build(1, m, 0); } } else { int x1, y1, z1, x2, y2, z2; scanf("%d %d %d %d %d %d", &x1, &y1, &z1, &x2, &y2, &z2); int ans = query(root, x1, y1, z1, x2, y2, z2); printf("%d\n", ans); } } } return 0;}
阅读全文
0 0
- HDU 5126 stars KDTree
- hdu 4347 kdtree kdtree+优先队列
- hdu 5126 stars cdq分治
- Hdu-5126 stars(cdq分治)
- HDU 4400-Mines-KDtree
- HDU 5992 (kdtree)
- HDU 4347 KNN+KDTree
- HDU 2966 KDtree模板
- HDU Stars
- Stars HDU
- HDU 5992 Finding Hotels KDtree
- HDU 5992 Finding Hotels KDtree
- hdu 5126 stars(三维空间cdq分治)
- HDU 5126 stars cdq分治+树状数组
- hdu 5126 stars ( CDQ分治 + 树状数组)
- HDU 5126 stars (CDQ分治)
- kdtree
- kdTree
- .NET面试题
- 【VUE】vue分页插件share
- 简单的右侧缩略栏风铃效果
- Python之List、Set、Tuple、Dictionary的区别
- Softmax回归原理简介+代码详解
- HDU 5126 stars KDTree
- struts2常量配置详解以及简单理解流程
- idea快捷键
- Python:pip使用中的问题(pip版本升级)
- JVM的Server/Client模式
- Goldbach`s Conjecture LightOJ 1259
- 开始写点博客啦~
- mnist数据集在caffe(windows)上的训练与测试及对自己手写数字的分类
- 51nod 1283 水题。。