time limit per test

5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard 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

【题解】

意思是说每个靶子离射击点的距离为z.然后描述矩形靶子的左下角和右下角。

射击m次。每次射击靶子之后。靶子会毁坏(假如同一个点有多个靶子重叠,最前面那个靶子坏掉。其他靶子还可以射击);

做法:

给每个子弹记录三个信息x,y,bianhao。即坐标以及各个子弹出现的先后顺序。

然后以靶子离射击点的距离为关键字从小到大排序。

处理第一个靶子是被哪一个子弹射击了。即在靶子所在范围内的子弹。且要求子弹的编号(射击顺序)最小。

这个问题可以用kd-tree来解决。

以子弹的点为元素建立kdtree

知道一个靶子是被哪个子弹射击之后。在kdtree中删掉这个子弹。然后继续处理下一个靶子。

编程复杂度很高。

【代码】

#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;
}; int n, m, root, now, txl, txr, tyl, tyr, 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;
}
} 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;
}
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;
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 x, target b,int fx)
{
return ((b.mi_n[fx] <= x) && (x <= b.ma_x[fx]));
} int query(int rt, int fx, int r, int xl, int xr, int yl, int yr)
{//r是当前处理的靶子编号 txl,txr,tyl,tyr是靶子信息。
//xl,xr,yl,yr是当前kd-tree的节点所在子树的所有点的范围(如果不确定就写成无穷大)
if (!rt)//我们会不断缩小这个范围。
return 0;
if (!t[rt].dot)
return 0;
if (txl <= xl && xr <= txr && tyl <= yl && yr <= tyr)
return t[rt].dot;
int t1 = 0,t2 = 0;
if (inrange(t[rt].d[fx], rec[r], fx))//这个节点的fx坐标在靶子范围内
{ //则左右儿子都要递归求解。则后序还要查看当前这个节点是否能更新。
if (fx == 0) //如果是以x轴排序
{
t1 = query(t[rt].l, 1-fx, r, xl, t[rt].d[0], yl, yr);
t2 = query(t[rt].r, 1-fx, r, t[rt].d[0], xr, yl, yr);
}
else//以y轴排序
{
t1 = query(t[rt].l, 1-fx, r, xl, xr, yl, t[rt].d[1]);
t2 = query(t[rt].r, 1-fx, r, xl, xr, t[rt].d[1], yr);
}
}
else//这个靶子的xy坐标没有完全把这个点包住
{//则只要返回左或右儿子
if (t[rt].d[fx] < rec[r].mi_n[fx])//大于这个节点的fx坐标 等号的情况上面已经考虑了
{
if (fx == 0)
return query(t[rt].r, 1-fx, r, t[rt].d[0], xr, yl, yr);
else
return query(t[rt].r, 1-fx, r, xl, xr, t[rt].d[1], yr);
}
if (rec[r].ma_x[fx] < t[rt].d[fx])//小于这个节点的fx坐标
{
if (fx == 0)
return query(t[rt].l, 1-fx, r, xl, t[rt].d[0], yl, yr);
else
return query(t[rt].l, 1-fx, r, xl, xr, yl, t[rt].d[1]);
}
}
int fi = 0; int temp = INF;
if (t1!=0)
if (t[t1].n < temp)//千万不要写成t[t1].min < temp
{//因为可能t[t1].min对应的点不在我们所需的范围内
//这个rt就已经返回的是所需的节点的编号了,不要乱来
temp = t[t1].n;
fi = t1;
}
if (t2 != 0)
if (t[t2].n < temp)
{
temp = t[t2].n;
fi = t2;
}
if (t[rt].n != 0 && t[rt].n < temp)//这是尝试用当前这个节点来更新。
if (inrange(t[rt].d[0],rec[r],0) && inrange(t[rt].d[1],rec[r],1))
{
temp = t[rt].n;
fi = rt;
}
return fi;
} 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++)
{
txl = rec[i].mi_n[0], txr = rec[i].ma_x[0], tyl = rec[i].mi_n[1], tyr = rec[i].ma_x[1];
int hit = query(root, 0, i, 0, INF, 0, INF);
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()
{
//freopen("F:\\rush.txt", "r", stdin);
input_data();
get_ans();
output_ans();
return 0;
}

【16.50%】【CF 44G】Shooting Gallery的更多相关文章

  1. 企业IT管理员IE11升级指南【16】—— 使用Compat Inspector快速定位IE兼容性问题

    企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...

  2. 【codeforces】【比赛题解】#851 CF Round #432 (Div.2)

    cf真的难…… 点我浏览丧题. [A]Arpa和她对墨西哥人浪的研究 Arpa正在对墨西哥人浪进行研究. 有n个人站成一排,从1到n编号,他们从时刻0开始墨西哥人浪. 在时刻1,第一个人站起来.在时刻 ...

  3. LeetCode:字母异位词分组【16】

    LeetCode:字母异位词分组[16] 题目描述 给定一个字符串数组,将字母异位词组合在一起.字母异位词指字母相同,但排列不同的字符串. 示例: 输入: ["eat", &quo ...

  4. LeetCode:最接近的三数之和【16】

    LeetCode:最接近的三数之和[16] 题目描述 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这 ...

  5. 【UOJ#50】【UR #3】链式反应(分治FFT,动态规划)

    [UOJ#50][UR #3]链式反应(分治FFT,动态规划) 题面 UOJ 题解 首先把题目意思捋一捋,大概就是有\(n\)个节点的一棵树,父亲的编号大于儿子. 满足一个点的儿子有\(2+c\)个, ...

  6. 【UOJ#242】【UR#16】破坏蛋糕(计算几何)

    [UOJ#242][UR#16]破坏蛋糕(计算几何) 题面 UOJ 题解 为了方便,我们假定最后一条直线是从上往下穿过来的,比如说把它当成坐标系的\(y\)轴. 于是我们可以处理出所有交点,然后把它们 ...

  7. JAVA 基础编程练习题50 【程序 50 文件 IO】

    50 [程序 50 文件 IO] 题目:有五个学生,每个学生有 3 门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩), 计算出平均成绩,将原有的数据和计算出的平均分数存放在磁盘文件&qu ...

  8. 【ABAP系列】【第五篇】SAP ABAP7.50 之用户接口

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列][第五篇]SAP ABAP7.5 ...

  9. 【ABAP系列】【第六篇】SAP ABAP7.50 之隐式增强

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列][第六篇]SAP ABAP7.5 ...

随机推荐

  1. WPF/Silverlight深度解决方案:(九)HLSL自定义渲染特效之完美攻略(下)

    原文:WPF/Silverlight深度解决方案:(九)HLSL自定义渲染特效之完美攻略(下) 本想只用两节来完成关于HLSL自定义渲染相关知识的讲解,鉴于最近非常的多的朋友对此相当感兴趣,想知道最多 ...

  2. Net Transport

    在调用第三方请求时,正确使用Client也不是一件非常容易的事. 下面是截取的一段描述,建议Client或Transport在整个服务期间最好是全局单例的,Transport本身会维护连接的状态,而且 ...

  3. python KMP算法介绍

  4. MongoDB sharding 集合不分片性能更高?

    最近云上用户用户遇到一个 sharding 集群性能问题的疑惑,比较有代表性,简单分享一下 测试配置 mongos x 2.shard x 3 测试1:集合不开启分片,批量 insert 导入数据,每 ...

  5. QT语言翻译

    QT中多语言的实现方式: 1.代码中tr运用 2.使用工具生成ts文件 3.翻译ts文件 4.生成qm文件 5.程序加载 以下内容程序加载时放入即可. QString appPath = QCoreA ...

  6. HTML之CSS标签

    1.CSS选择器 1).id选择器   2).class选择器 3).标签选择器   4).层级选择器(空格)    (1)id层级选择器       (2)class层级选择器 5).组合选择器(逗 ...

  7. List容器-ArrayList

    特点:   有序重复,包括null,通过整数索引访问 实现类ArrayList和LinkedList ArrayList--动态数组   不线程同步  单线程合适 List<String> ...

  8. 【JZOJ4869】【NOIP2016提高A组集训第9场11.7】平均数

    题目描述 数据范围 解法 二分答案. 对于一个答案mid,要求出区间平均数小于mid的个数ans. 给所有数减去mid,那么问题转化为求出所有区间和为负数的个数. 对于一个区间[l,r],如果sum[ ...

  9. Quick BI独创千人千面的行级权限管控机制

    摘要 就数据访问权限而言,阿里巴巴以“被动式授权”为主,你需要什么权限就申请什么权限.但是,在客户交流过程中,我们发现绝大多数企业都是集中式授权,尤其是面向个人的行级权限管控,管理复杂度往往呈几何增长 ...

  10. 从零学React Native之08Image组件

    开发过程中, 几乎每个项目都会用到图片. RN就是通过Image组件显示图片.既可以加载网络图片,也可以加载本地资源图片. Image组件必须在样式中声明图片的款和高.如果没有声明,则图片将不会被呈现 ...