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. 千亿级平台技术架构:为了支撑高并发,我把身份证存到了JS里

    @ 目录 一.用户信息安全规范 1.1 ​用户信息.敏感信息定义及判断依据 1.1.1 个人信息 1.1.2 个人敏感信息 1.2 ​用户信息存储的注意事项 二.​框架技术实现 2.1 用户敏感信息自 ...

  2. 复习python的__call__ __str__ __repr__ __getattr__函数 整理

    class Www: def __init__(self,name): self.name=name def __str__(self): return '名称 %s'%self.name #__re ...

  3. G - Harmonic Number (II) LightOJ - 1245

    算是一个找规律的题目吧. 枚举前sqrt(n)个数,数i出现的次数为n/i-n/(i+1),对答案的贡献为(n/i-n/(i+1))*i. 对于sqrt后边的数,可以直接由n/i获得,并且一定只出现一 ...

  4. 史上最详细的VM虚拟机安装Kali-linux教程(以2020.1版本为例,含下载地址+默认提升为root权限)

    一.官方下载 Kali Linux 官方网址:www.Kali.org下载方式分两种:http 下载和 bt 下载(由于是国外网站 http 方式下载会非常慢),选择对应版本点击即可下载. 二.创建新 ...

  5. cmd 文件/文件夹的一切操作

    dir // 列出目录下所有文件夹 rd dirname // 删除dirname文件夹(空文件夹) rd /s/q dirname // 删除dirname文件夹(非空)

  6. WEBMIN(CVE-2019-15107) 学习

    简单介绍: Webmin是目前功能最强大的基于Web的Unix系统管理工具.管理员通过浏览器访问Webmin的各种管理功能并完成相应的管理动作.目前Webmin支持绝大多数的Unix系统,这些系统除了 ...

  7. selemiun 问题总结

    1.如果打开一个网页定位一个元素时发现不能够定位某一个元素,并且定位的方法没问题,则需要看下该网页是否有frame框架 解决办法: 如果有frame框架则需要先切换到frame框架下: driver. ...

  8. mongodb connection refused because too many open connections: 819

    Env Debian 9 # 使用通用二进制方式安装 # mongod --version db version v3.4.21-2.19 git version: 2e0631f5e0d868dd5 ...

  9. py安装教程

    https://www.runoob.com/w3cnote/pycharm-windows-install.html

  10. 20199310《Linux内核原理与分析》第十五周作业 Linux安全实验

    1 补充知识 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭, ...