经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
BZOJ5462: [APIO2018] 新家(K-D Tree)
来源:cnblogs  作者:自为风月马前卒  时间:2018/12/7 9:33:26  对本文有异议

题意

题目链接

Sol

下面是错误做法,正解请看这里

考虑直接用K-D tree模拟。。

刚开始想的是维护矩形最大最小值,以及子树中最大圆的位置,然后。。。

实际上最大圆的位置是不用维护的,直接把原序列排一遍序就可以了

再努力卡卡常就过了

如果还过不了的话可以尝试把所有点都转一个角度

  1. // luogu-judger-enable-o2
  2. #include<bits/stdc++.h>
  3. #define chmin(x, y) (x = x < y ? x : y)
  4. #define chmax(x, y) (x = x > y ? x : y)
  5. #define ls(x) T[k].ls
  6. #define rs(x) T[k].rs
  7. #define double long double
  8. const double alpha(acos(-1) / 5);
  9. const double cosa(cos(alpha));
  10. const double sina(sin(alpha));
  11. using namespace std;
  12. const int MAXN = 1e6 + 10;
  13. const double INF = 1e12 + 10, eps = 1e-11;
  14. inline int read() {
  15. char c = getchar(); int x = 0, f = 1;
  16. while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
  17. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  18. return x * f;
  19. }
  20. int N, WD, root, tot, num, ans[MAXN];
  21. struct Point {
  22. double x[2], r;
  23. int id;
  24. bool operator < (const Point &rhs) const {
  25. return rhs.x[WD] - x[WD] > eps;
  26. }
  27. double operator [] (const int d) {
  28. return x[d];
  29. }
  30. }P[MAXN];
  31. int comp(const Point &a, const Point b) {
  32. return a.r == b.r ? a.id < b.id : a.r > b.r;
  33. }
  34. struct Node {
  35. int ls, rs, id;
  36. double mx[2], mi[2];
  37. Point p;
  38. }T[MAXN];
  39. void update(int k) {
  40. for(int i = 0; i <= 1; i++) {
  41. if(!ans[T[k].id]) T[k].mi[i] = T[k].p[i] - T[k].p.r, T[k].mx[i] = T[k].p[i] + T[k].p.r;
  42. else T[k].mi[i] = INF, T[k].mx[i] = -INF;
  43. if(ls(k)) chmin(T[k].mi[i], T[ls(k)].mi[i]), chmax(T[k].mx[i], T[ls(k)].mx[i]);
  44. if(rs(k)) chmin(T[k].mi[i], T[rs(k)].mi[i]), chmax(T[k].mx[i], T[rs(k)].mx[i]);
  45. }
  46. }
  47. int Build(int l, int r, int wd) {
  48. if(l > r) return 0;
  49. WD = wd; int mid = (l + r) >> 1, k = ++tot;
  50. nth_element(P + l, P + mid, P + r + 1);
  51. T[k].p = P[mid]; T[k].id = P[mid].id;
  52. T[k].ls = Build(l, mid - 1, wd ^ 1) ;
  53. T[k].rs = Build(mid + 1, r, wd ^ 1);
  54. update(k);
  55. return k;
  56. }
  57. double sqr(double x) {
  58. return x * x;
  59. }
  60. bool judge(Point a, Point b) {
  61. double tmp = sqr(a[0] - b[0]) + sqr(a[1] - b[1]);
  62. return sqr(a.r + b.r) + eps - tmp > 0;
  63. }
  64. bool pd(int k, Point a) {
  65. for(int i = 0; i <= 1; i++)
  66. if((a[i] + a.r + eps < T[k].mi[i]) || (a[i] - a.r - eps > T[k].mx[i])) return 1;
  67. return 0;
  68. }
  69. void Delet(int k, Point a) {
  70. if(pd(k, a)) return ;
  71. if(!ans[T[k].id] && judge(T[k].p, a)) ans[T[k].id] = a.id, T[k].p.r = -INF, num++;
  72. if(ls(k)) Delet(ls(k), a);
  73. if(rs(k)) Delet(rs(k), a);
  74. update(k);
  75. }
  76. int main() {
  77. //freopen("a.in", "r", stdin);
  78. N = read();
  79. for(int i = 1; i <= N; i++) {
  80. double x = read(), y = read(), tx = x * cosa - y * sina, ty = x * sina + y * cosa;
  81. P[i].x[0] = x; P[i].x[1] = y; P[i].r = read(), P[i].id = i;
  82. }
  83. root = Build(1, N, 0);
  84. sort(P + 1, P + N + 1, comp);
  85. for(int i = 1; i <= N; i++) if(!ans[P[i].id]) Delet(root, P[i]);
  86. for(int i = 1; i <= N; i++) printf("%d ", ans[i]);
  87. return 0;
  88. }
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号