time limit per test5 seconds

memory limit per test256 megabytes

inputstandard input

outputstandard output

Berland amusement park shooting gallery is rightly acknowledged as one of the best in the world. Every day the country’s best shooters master their skills there and the many visitors compete in clay pigeon shooting to win decent prizes. And the head of the park has recently decided to make an online version of the shooting gallery. During the elaboration process it turned out that the program that imitates the process of shooting effectively, is needed. To formulate the requirements to the program, the shooting gallery was formally described. A 3D Cartesian system of coordinates was introduced, where the X axis ran across the gallery floor along the line, along which the shooters are located, the Y axis ran vertically along the gallery wall and the positive direction of the Z axis matched the shooting direction. Let’s call the XOY plane a shooting plane and let’s assume that all the bullets are out of the muzzles at the points of this area and fly parallel to the Z axis. Every clay pigeon can be represented as a rectangle whose sides are parallel to X and Y axes, and it has a positive z-coordinate. The distance between a clay pigeon and the shooting plane is always different for every target. The bullet hits the target if it goes through the inner area or border of the rectangle corresponding to it. When the bullet hits the target, the target falls down vertically into the crawl-space of the shooting gallery and cannot be shot at any more. The targets are tough enough, that’s why a bullet can not pierce a target all the way through and if a bullet hits a target it can’t fly on. In input the simulator program is given the arrangement of all the targets and also of all the shots in the order of their appearance. The program should determine which target was hit by which shot. If you haven’t guessed it yet, you are the one who is to write such a program.

Input

The first line contains an integer n (1 ≤ n ≤ 105) — the number of targets. Each of the subsequent n lines contains the description of a target. The target is described by five integers xl, xr, yl, yr, z, that determine it’s location in space (0 ≤ xl < xr ≤ 107, 0 ≤ yl < yr ≤ 107, 0 < z ≤ 107). The next line contains an integer m (1 ≤ m ≤ 105), determining the number of shots. Then in m lines shots are described. Every shot is determined by the coordinates of a bullet on the shooting plane (x, y) (0 ≤ x, y ≤ 107, the coordinates of bullets are integers). The shots are given in the order of their firing. The intervals between shots are large enough, and a target falls very quickly, that’s why assume that a falling target can not be an obstruction for all the shots following the one that hit it.

Output

For every shot in the single line print the number of the target which the shot has hit, or 0, if the bullet did not hit any target. The targets are numbered starting from 1 in the order in which they were given in the input data.

Examples

input

2

1 4 1 4 1

2 5 2 6 2

4

0 0

3 3

4 5

3 5

output

0

1

2

0

【题解】



给你n个靶子;

m个子弹;

问每个子弹能打到哪些靶子;

当然子弹打到靶子之后;那个靶子就会消失;

kd-tree把子弹作为元素加进去;

然后把每个靶子按照距离z升序排(顺序处理);

给每个靶子找子弹(这个靶子所在的范围里面子弹的顺序最小的那个);

然后把那个子弹从kd-tree中删掉;

继续找就好;

涉及到了kd-tree节点的删除;

#include <cstdio>
#include <algorithm> using namespace std; const int MAXN = 105000;
const int INF = 2100000000; struct target
{
int mi_n[2], ma_x[2], z, n;
}; struct point
{
int min, n, dot, d[2],fa,l,r,ma_x[2],mi_n[2];
}; int n, m, root, now,ans[MAXN] = { 0 }; target rec[MAXN];
point t[MAXN]; void input_data()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d%d%d%d%d", &rec[i].mi_n[0], &rec[i].ma_x[0], &rec[i].mi_n[1], &rec[i].ma_x[1], &rec[i].z);
rec[i].n = i;
}
scanf("%d", &m);
for (int i = 1; i <= m; i++)
{
scanf("%d%d", &t[i].d[0], &t[i].d[1]);
t[i].n = i;
}
} bool cmp_1(point a, point b)
{
return a.d[now] < b.d[now];
} void gengxin(int father, int son)
{
if (t[father].min > t[son].min)
{
t[father].min = t[son].min;
t[father].dot = t[son].dot;
}
for (int i = 0;i <= 1;i++)
{
t[father].mi_n[i] = min(t[father].mi_n[i],t[son].mi_n[i]);
t[father].ma_x[i] = max(t[father].ma_x[i],t[son].ma_x[i]);
}
} void up_data(int rt)
{
t[rt].min = t[rt].n; t[rt].dot = rt; //dot可以说是当前这个子树的编号最小的点的节点。
if (t[rt].n == 0) //如果点已经删掉了
{
t[rt].min = INF;
t[rt].dot = 0;
t[rt].mi_n[0] = INF;
t[rt].mi_n[1] = INF;
t[rt].ma_x[0] = 0;
t[rt].ma_x[1] = 0;
}
int l = t[rt].l, r = t[rt].r;
if (l)
gengxin(rt, l);
if (r)
gengxin(rt, r);
} int build(int begin, int end, int fa,int fx)
{
int m = (begin + end) >> 1;
now = fx;
nth_element(t + begin, t + m, t + end + 1, cmp_1);
t[m].fa = fa;
for (int i = 0;i<=1;i++)
t[m].mi_n[i] = t[m].ma_x[i] = t[m].d[i];
if (begin < m)
t[m].l = build(begin, m - 1, m, 1 - fx);
if (m < end)
t[m].r = build(m + 1, end, m, 1 - fx);
up_data(m);
return m;
} bool inrange(int a,int b,int c)
{
return (a<=b && b <=c);
} int query(int rt,int r)
{
if (!rt)
return 0;
if (!t[rt].dot)
return 0;
if (rec[r].mi_n[0] <= t[rt].mi_n[0] && t[rt].ma_x[0] <= rec[r].ma_x[0]
&& rec[r].mi_n[1] <= t[rt].mi_n[1] && t[rt].ma_x[1] <= rec[r].ma_x[1])//这个子树里面的子弹全部在靶子的范围内;
return t[rt].dot;
if (rec[r].mi_n[0]>t[rt].ma_x[0] || rec[r].ma_x[0] < t[rt].mi_n[0] ||//全不在就结束
rec[r].mi_n[1]>t[rt].ma_x[1] || rec[r].ma_x[1] < t[rt].mi_n[1])
return 0;
int temp = 0;
if ( t[rt].n!=0 && rec[r].mi_n[0] <= t[rt].d[0] && t[rt].d[0] <= rec[r].ma_x[0]//当前这个节点;
&& rec[r].mi_n[1] <= t[rt].d[1] && t[rt].d[1] <= rec[r].ma_x[1])
temp = rt;
int zuo = t[rt].l,you = t[rt].r;
int temp1 = query(zuo,r);//递归处理左右节点
int temp2 = query(you,r);
if (temp1 !=0)
if (!temp)
temp = temp1;
else
{
if (t[temp1].n<t[temp].n)//注意不是把temp赋值成t[temp1].n;
temp = temp1;
}
if (temp2 !=0)
if (!temp)
temp = temp2;
else
if (t[temp2].n < t[temp].n)
temp = temp2;
return temp;
} void adjust(int rt) //删掉一个点后调整相关点的信息
{
up_data(rt);
if (rt != root)
adjust(t[rt].fa);
} bool cmp_2(target a, target b)
{
return a.z < b.z;
} void get_ans()
{
root = build(1, m, 0, 0);
sort(rec + 1, rec + 1 + n, cmp_2);
for (int i = 1; i <= n; i++)
{
now = i;
int hit = query(root, i);
if (hit != 0)
{
ans[t[hit].n] = rec[i].n;
t[hit].n = 0;
adjust(hit);
}
}
} void output_ans()
{
for (int i = 1; i <= m; i++)
printf("%d\n", ans[i]);
} int main()
{
input_data();
get_ans();
output_ans();
return 0;
}

最新文章

  1. 浅谈一下关于iscroll的使用心得
  2. Unity3D逻辑热更新,第二代舒爽解决方案,L#使用简介
  3. oracle中的timestamp字段的值乱码问题修改
  4. python获取外网地址
  5. Twenty Newsgroups Classification任务之二seq2sparse(3)
  6. meta标签的含义
  7. 跟我学android-Android应用基本组件介绍(五)
  8. ASP.NET Web Service应用发布到IIs怎么做
  9. 如何与多个线程的操作epoll fd
  10. 关于tomcat 成功运行之后内存泄露
  11. bestcoder round 74 div2
  12. React-router v4教程
  13. python常见的报错提示
  14. 【PHP篇】变量与常量
  15. 福州大学软件工程1816 | W班 第2次作业成绩排名
  16. Spring:获取容器中的Bean
  17. 阶段01Java基础day16集合框架02
  18. mui项目中如何使用原生JavaScript代替jquery来操作dom
  19. myapplication 单例写法
  20. Visual Studio 2017 远程调试(Remote Debugger)应用

热门文章

  1. java方法调用之动态调用多态(重写override)的实现原理——方法表(三)
  2. 使用Intent的Flag设置启动參数
  3. POJ 2236 Wireless Network ||POJ 1703 Find them, Catch them 并查集
  4. (转)Oracle EXP-00091解决方法
  5. Android 仿今日头条频道管理(下)(GridView之间Item的移动和拖拽)
  6. 10.10 android输入系统_APP获得并处理输入事件流程
  7. nginx 代理服务器
  8. C++中的虚析构函数、纯虚析构函数具体解释
  9. 如何用Swift创建一个复杂的加载动画
  10. swift学习第七天:字典