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 线段树扫描线的更多相关文章
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- 【POJ-2482】Stars in your window 线段树 + 扫描线
Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11706 Accepted: ...
- HDU 4419 Colourful Rectangle --离散化+线段树扫描线
题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...
- BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤
3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...
- BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞
看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...
- hdu 5091(线段树+扫描线)
上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...
- POJ1151+线段树+扫描线
/* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
随机推荐
- mysql 不能对同一个表进行 update(delete) 和 select 联合操作
eq: update a set a.x = 1 where a.y in (select a.x from a); 上边语法是错误的,在对aupdate 时不能再条件中对同一个a表进 ...
- Restlet Client发送GET、POST等请求
插件下载 百度云盘 链接:https://pan.baidu.com/s/13R4s1UR5TONl2JnwTgtIYw 密码:rt02 插件安装 解压后,直接拖进浏览器中. 功能演示
- 如何从零开始学Python?会玩游戏就行,在玩的过程就能掌握编程
现在学习编程的人很多,尤其是python编程,都列入高考了,而且因为人工智能时代的到来,编程也将是一门越来越重要的技能. 但是怎么从零开始学python比较好呢?其实,你会玩游戏就行. 从零基础开始教 ...
- L6循环神经网络
循环神经网络 本节介绍循环神经网络,下图展示了如何基于循环神经网络实现语言模型.我们的目的是基于当前的输入与过去的输入序列,预测序列的下一个字符.循环神经网络引入一个隐藏变量HHH,用HtH_{t}H ...
- 10.添加script标签,判断onload是否完成
class Tools { static loadScript(url, callback) { let old_script = document.getElementById(url); if ( ...
- kubernetes删除pod,pod一直处于Terminating状态
删除pod,pod一直处于Terminating状态 [root@yxz-cluster01 deploy_yaml]# kubectl get pod -n yunanbao NAME READY ...
- Redis学习与应用-位图
什么是位图 位图bitmap是通过一个bit来表示某个元素对应的值或者状态,是由一组bit位组成,每个bit位对应0和1两个状态,虽然内部还是采用string类型进行存储,但是redis提供了直接操作 ...
- 作业十一——LL(1)文法的判断,递归下降分析程序
作业十一——LL(1)文法的判断,递归下降分析程序 判断是否为LL(1)文法 选取有多个产生式的求select,只有一条产生式的无需求select 同一个非终结符之间求交集,全部判断为空后则为LL(1 ...
- DDOS攻击攻击种类和原理
DoS攻击.DDoS攻击和DRDoS攻击相信大家已经早有耳闻了吧!DoS是Denial of Service的简写,就是拒绝服务,而DDoS就是Distributed Denial of Servic ...
- Libra教程之:Libra protocol的逻辑数据模型
文章目录 Libra protocol简介 逻辑数据模型 账本状态 交易 账本历史 Libra protocol简介 Libra区块链本质上是一个加密数据库,这个数据库是通过Libra protoco ...