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. 逆拓扑排序 Reward HDU - 2647

    Reward HDU - 2647 题意:每个人的起始金额是888,有些人觉得自己做的比另一个人好所以应该多得一些钱,问最少需要花多少钱,如果不能满足所有员工的要求,输出 -1 样例1: 2 1 1 ...

  2. AJ学IOS 之控制器view显示中view的父子关系及controller的父子关系_解决屏幕旋转不能传递事件问题

    AJ分享,必须精品 一:效果 二:项目代码 这个Demo用的几个控制器分别画了不通的xib,随便拖拽了几个空间,主要是几个按钮的切换,主要代码展示下: // // NYViewController.m ...

  3. java的多线程是如何实现的?和操作系统有什么关系?

    本文是作者原创,版权归作者所有.若要转载,请注明出处.本文只贴我觉得比较重要的源码,其他不重要非关键的就不贴了 本文操作系统是centos7 1.查看 pthread_create 函数显示及其示例 ...

  4. linux基础知识点扫描

    1.tty:查看自己的虚拟终端 2.echo "你的服务器已经被我控制,请立刻打钱给我,账号12312312312314123421,否则后果自负!!!"  >  /dev/ ...

  5. Hadoop权威指南(中文版-带目录索引)pdf电子书

      Hadoop权威指南(中文版-带目录索引)pdf电子书下载地址:百度网盘点击下载:链接:https://pan.baidu.com/s/1E-8eLaaqTCkKESNPDqq0jw 提取码:g6 ...

  6. vue2.x学习笔记(二十)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12631279.html. 循环引用 递归组件 组件是可以在它们自己的模板中调用自身的,不过它们只能通过[name] ...

  7. AI vs PS 矢量 VS 位图

    矢量图 AI最大可以放大64000%.不会失真,依然很清晰.原理是不同的点以及点与点之间的路径构成的,不论放大的多大,点在路径在,就可以精确的计算出它的区域.AI中无法直接编辑位图. 位图 代表PS, ...

  8. 1. git 本地给远程仓库创建分支 三步法

    命令如下: 1:本地创建分支dev 1 2 Peg@PEG-PC /D/home/myself/Symfony (master) $ git branch dev 2:下面是把本地分支提交到远程仓库 ...

  9. 转:Cookies 和 Session的区别

    转自:http://blog.csdn.net/axin66ok/article/details/6175522 1.cookie 是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在 ...

  10. 吕建文 20199303《Linux内核原理与分析》第十二周作业

    ShellShock攻击实验 2014年9月24日,Bash中发现了一个严重漏洞shellshock,该漏洞可用于许多系统,并且既可以远程也可以在本地触发.在本实验中,学生需要亲手重现攻击来理解该漏洞 ...