PUBG 1V3

这个题目我觉得好难写啊。

感觉自己码力不太行啊。

题目大意是,给你n个人,n个人组成m个队伍,每个队伍最多4个人。

然后给你每一个人的位置队伍信息还有攻击范围。

问当一个队伍剩下一个人的时候他最多可以杀多少个人。

这个题目是有扫描线的思想。

首先我们用一个结构体来存更新点的信息,然后用一个结构体来存查询边的信息。

然后像扫描线一样的对点和边进行排序。

然后更新点的信息,如果到了要查询边的信息就查询。

最后统计答案。

这个大体思路还是比较简单,但是这个细节的处理很麻烦。

因为对于每一个人如果是他的队友肯定是不可以杀的,所以要删去这些点,这个就用前向星类似的方式去存它队友所存放的

数组的编号,但是这样就说明不可以直接对结构体排序,所以这个时候有一个小小的技巧就是用一个数组来排序,结构体本身不打乱顺序。

还有就是如何判断到查询边的信息的时候呢?就是如果更新下一个点的时候的y都大于这个查询边的信息,那就查询。

然后就是要注意范围,因为x,y的范围是1e6的绝对值,如果超出这个范围的查询的边都是0。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 1e6 + 10; struct node
{
int x, y, team, nxt, d;
node(int x=0,int y=0,int team=0,int nxt=0,int d=0):x(x),y(y),team(team),nxt(nxt),d(d){}
}ex[maxn]; struct edge
{
int l, r, y, f, id;
edge(int l=0,int r=0,int y=0,int f=0,int id=0):l(l),r(r),y(y),f(f),id(id){}
}que[maxn*4];
int p[maxn];
int head[maxn];
bool cmp1(edge a,edge b)
{
return a.y < b.y;
}
bool cmp2(int a,int b)
{
return ex[a].y < ex[b].y;
}
int ans[maxn], end_ans[maxn];
int num[maxn * 10]; void update(int id,int l,int r,int pos)
{
if(l==r)
{
num[id] += 1;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) update(id << 1, l, mid, pos);
else update(id << 1 | 1, mid + 1, r, pos);
num[id] = num[id << 1] + num[id << 1 | 1];
} int query(int id,int l,int r,int x,int y)
{
if (x <= l && y >= r) return num[id];
int mid = (l + r) >> 1;
int ans = 0;
if (x <= mid) ans += query(id << 1, l, mid, x, y);
if (y > mid) ans += query(id << 1 | 1, mid + 1, r, x, y);
return ans;
} int main()
{
int n, m, cnt = 0;
scanf("%d%d", &n, &m);
memset(head, -1, sizeof(head));
memset(num, 0, sizeof(num));
for (int i = 1; i <= n; i++) {
p[i] = i;
int x, y, d, team;
scanf("%d%d%d%d", &x, &y, &d, &team);
ex[i] = node(x, y, team, head[team], d);
head[team] = i;
int l = max(-maxn + 1, x - d);
int r = min(maxn - 1, x + d);
int h = min(maxn - 1, y + d);
que[cnt++] = edge(l, r, h, 1, i);
// printf("que[%d] id=%d\n", cnt, i);
h = max(-maxn + 1, y - d) - 1;
que[cnt++] = edge(l, r, h, -1, i);
// printf("que[%d] id=%d\n", cnt, i);
}
sort(que, que + cnt, cmp1);
sort(p + 1, p + 1 + n, cmp2);
int tot = 1;
for (int i = 0; i < cnt; i++) {
while (tot <= n && ex[p[tot]].y <= que[i].y) {
// printf("tot=%d x=%d\n", tot, ex[p[tot]].x);
update(1, 1, maxn * 2, ex[p[tot]].x + maxn);
tot++;
}
ans[que[i].id] += que[i].f*query(1, 1, maxn * 2, que[i].l + maxn, que[i].r + maxn);
// printf("l=%d r=%d h=%d\n", que[i].l, que[i].r, que[i].y);
// printf("i=%d ans[%d]=%d\n\n",i, que[i].id, ans[que[i].id]);
}
for (int i = 1; i <= n; i++) {
int team = ex[i].team;
int x = ex[i].x, y = ex[i].y, d = ex[i].d;
for (int j = head[team]; j != -1; j = ex[j].nxt) {
// printf("id=%d j=%d\n", id, j);
int x1 = ex[j].x, y1 = ex[j].y;
if (abs(x1 - x) <= d && abs(y1 - y) <= d) ans[i]--;
}
end_ans[team] = max(end_ans[team], ans[i]);
}
int q;
scanf("%d", &q);
while(q--)
{
int id;
scanf("%d", &id);
printf("%d\n", end_ans[id]);
}
return 0;
}

  

PUBG 1V3 线段树扫描线的更多相关文章

  1. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  2. Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D 题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...

  3. 【POJ-2482】Stars in your window 线段树 + 扫描线

    Stars in Your Window Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11706   Accepted:  ...

  4. HDU 4419 Colourful Rectangle --离散化+线段树扫描线

    题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...

  5. BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤

    3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...

  6. BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞

    看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...

  7. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  8. POJ1151+线段树+扫描线

    /* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...

  9. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

随机推荐

  1. shell map数据结构的实现

    前言     Bash默认不支持二维数组,如果我们想实现map 数据结构,可以安装如下的方式来进行构造   预备知识     eval:  它是shell内建命令,用于字符串的解析.它会首先扫描命令行 ...

  2. 做一个通过dockerfile从零构建centos7.4

    今天做一个dockerfile从零构建centos7.4镜像 废话不多说,很简单. 需要的软件包:centos7.4的rootfs 链接:提取码:usnu 下载以后我们打开看看里面是什么呢: 可以看的 ...

  3. Android MonkeyTalk测试

    Android MonkeyTalk测试 MonkeyTalk可以用于压力测试,正因为这点所以才选择MonkeyTalk进行测试,相对于Monkey测试,目前个人发现的有点在于,MonkeyTalk是 ...

  4. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions

    The ideal time to catch an error is at compile time, before you even try to run the program. However ...

  5. BUG 测试计划

       性能追求 目前状况 测试标准 APP平稳运行,无crush现象   快速下拉翻页时,崩溃退出     要求多人使用,均流畅无异常退出方可               页面的放大缩小不会造成页面显 ...

  6. EOS基础全家桶(八)jungle测试网的使用

    简介 前面我们已经学习了一些EOS的基础知识了,但是在EOS主网上的很多操作(比如:抵押.赎回.买卖内存)都是需要EOS链被正式激活后才可使用,而激活EOS链还需要很多的准备操作,我打算在单独的一篇文 ...

  7. Java SE —— 专栏总集篇

    前言: Java 语言,是相对于其他语言而言,门槛低,而且功能还强大的一门编程语言,本人十分看好这一门语言,但是,它也是有深度的,看过本人的<数据结构与算法>专栏的同学们有福了,因为本人在 ...

  8. SringMVC入门程序

    Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架 1.Spring优点 轻量级,简单易学 高效 , 基于请求响应的MVC框架 与Spring兼 ...

  9. <vector>常用操作

    如果不清楚vector是什么的话就去看我的另一篇随笔吧:https://www.cnblogs.com/buanxu/p/12791785.html 进入正题,vector和string一样,也是一种 ...

  10. thinkphp5 input坑

    取值方式改了而已?a1=1&a2=2这种可以用input(get.) a1/1/a2/2 用input('a1')和input('a2') post方法当然是input('post.') 我觉 ...