牛客多校第十场 F Popping Balloons 线段树维护稀疏矩阵
题意:
给定一个稀疏矩阵,里面有若干个气球,让你横着开三枪,竖着开三枪,问最多能打爆多少气球,要求相同方向,相邻两枪必须间隔r。
题解:
横向记录每列有多少个气球,分别在哪行上。
然后把这个数据改造成以此点为左端点,此列,以及此行右r列,以及右2r列的信息。
纵向记录每行有多少个气球。
然后将此数据改造成以此点为下端点,此行,上r行,上2r行的信息。
将每行有多少个气球用线段树维护。
枚举竖着开枪的左端点,在线段树上删去那些竖着打爆的气球,然后询问线段树根节点,树上叶节点权值最大为几,就是横着三枪能打爆的最多气球数。
再把横着打爆的和竖着打爆的加起来维护最大值。
再把删掉的气球加回来。
由于矩阵为稀疏矩阵,因此保证在整个横向枚举过程,访问的节点是O(n)的。
#include<iostream>
#include<vector>
#define MAXN 100005
#define LL long long
using namespace std;
struct Node{
int l,r;
// int sum;
int maxx;
}node[MAXN<<]; int killy[MAXN];//选择此点为y轴下端点消灭的气球数
vector<int> killx[MAXN];//选择此点为x轴左端点能够消灭哪些气球 void build(int l,int r,int x){
node[x].l=l;
node[x].r=r;
if(l==r){
// node[x].sum=killy[l];
node[x].maxx=killy[l];
return ;
}else{
int mid=(l+r)/;
build(l,mid,x*);
build(mid+,r,x*+);
}
// node[x].sum=node[2*x].sum+node[2*x+1].sum;
node[x].maxx=max(node[*x].maxx,node[*x+].maxx);
return ;
}
void add(int id,int x,int num){
if(node[x].l==node[x].r){
// node[x].sum+=num;
node[x].maxx+=num;
return ;
}
if(id<=node[x*].r){
add(id,x*,num);
}else{
add(id,x*+,num);
}
// node[x].sum=node[2*x].sum+node[2*x+1].sum;
node[x].maxx=max(node[*x].maxx,node[*x+].maxx);
return ;
}
int main(){
int n,r;
int max_x=,max_y=;
scanf("%d %d",&n,&r); for(int i=;i<=n;i++){
int x,y;
scanf("%d %d",&x,&y);
x++;
y++;
max_x=max(max_x,x);
max_y=max(max_y,y); killy[y]++;
if(y-r>)killy[y-r]++;
if(y-r-r>)killy[y-r-r]++; killx[x].push_back(y);
if(x-r>)killx[x-r].push_back(y);
if(x-r-r>)killx[x-r-r].push_back(y);
}
build(,max_y,);
int sum=,ans=; // printf("%d\n",node[1].maxx);
// for(int i=1;i<=25;i++){
// printf("i:%d l:%d r:%d maxx:%d\n",i,node[i].l,node[i].r,node[i].maxx);
// } for(int i=;i<=max_x;i++){
sum=killx[i].size();
for(int j=;j<killx[i].size();j++){
// printf("%d\n",killx[i][j]);
add(killx[i][j],,-);
if(killx[i][j]-r>)add(killx[i][j]-r,,-);
if(killx[i][j]-r-r>)add(killx[i][j]-r-r,,-);
} // for(int kk=1;kk<=25;kk++){
// printf("l:%d r:%d maxx:%d\n",node[kk].l,node[kk].r,node[kk].maxx);
// } sum+=node[].maxx;
// printf("x:%d xkill:%d ykill:%d\n",i,killx[i].size(),node[1].maxx);
ans=max(sum,ans);
for(int j=;j<killx[i].size();j++){
add(killx[i][j],,);
if(killx[i][j]-r>)add(killx[i][j]-r,,);
if(killx[i][j]-r-r>)add(killx[i][j]-r-r,,);
} }
printf("%d\n",ans);
return ;
}
牛客多校第十场 F Popping Balloons 线段树维护稀疏矩阵的更多相关文章
- 牛客多校第四场sequence C (线段树+单调栈)
牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...
- 2019年牛客多校第四场 B题xor(线段树+线性基交)
题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...
- 2019牛客多校第四场C-sequence(单调栈+线段树)
sequence 题目传送门 解题思路 用单调栈求出每个a[i]作为最小值的最大范围.对于每个a[i],我们都要乘以一个以a[i]为区间内最小值的对应的b的区间和s,如果a[i] > 0,则s要 ...
- 牛客多校第七场 C Governing sand 线段树
题意: 有一个树林,树林中不同种类的树有不同的数量,高度,砍伐它们的价格.现在要求砍掉一些树,使得高度最高的树占剩下的树的总数的一半以上,求最小花费. 题解: 用线段树维护不同种类树的信息,叶子节点从 ...
- 牛客多校第三场 F Planting Trees
牛客多校第三场 F Planting Trees 题意: 求矩阵内最大值减最小值大于k的最大子矩阵的面积 题解: 矩阵压缩的技巧 因为对于我们有用的信息只有这个矩阵内的最大值和最小值 所以我们可以将一 ...
- 2019牛客多校第八场 F题 Flowers 计算几何+线段树
2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...
- 牛客多校第五场 F take
链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 题目描述 Kanade has n boxes , the i-th box has p[i] ...
- 牛客多校第四场 F Beautiful Garden
链接:https://www.nowcoder.com/acm/contest/142/F来源:牛客网 题目描述 There's a beautiful garden whose size is n ...
- 牛客多校第十场 A Rikka with Lowbit 线段树
链接:https://www.nowcoder.com/acm/contest/148/A来源:牛客网 题目描述 Today, Rikka is going to learn how to use B ...
随机推荐
- springcloud笔记一
微服务的概述 什么是微服务? 现今微服务界没有一个统一的.标准的定义 微服务化的核心就是将统一的一站式应用,根据业务拆分成一个一个的服务,彻底的去耦合,每一个微服务提供单个业务功能的服务,一个服务做一 ...
- mongodb客户端操作常用命令(续)
之前有写过一篇mongodb客户端的操作常用命令 ,今天接着来记录分享一些关于mongodb账户权限设置的命令操作 上期mongodb客户端的操作常用命令地址:https://www.cnblogs. ...
- 【Flutter学习】基本组件之基本列表ListView组件
一,概述 列表是前端最常见的需求. 在flutter中,用ListView来显示列表页,支持垂直和水平方向展示,通过一个属性我们就可以控制其方向,列别有以下分类 水平列表 垂直列表 数据量非常大的列表 ...
- 管理员技术(一):装机预备技能、安装一台RHEL7虚拟机、使用RHEL7图形桌面、Linux命令行基本操作
一.装机预备技能 问题: 本例要求安装一台可用的KVM服务器: 1> RHEL与CentOS系统有什么关联? 2> 第2块SCSI硬盘的第3个逻辑分区,Linux如何表 ...
- [Luogu P4178]Tree 题解(点分治+平衡树)
题目大意 给定一棵树,边带权,问有多少点对满足二者间距离$\leq K$,$n \leq 40000$. 题解 点分治专题首杀!$Jackpot!$ (本来看着题意比较简单想捡个软柿子捏,结果手断了… ...
- linq中如何合并多个predicate条件
最近在做一个webAPI 的时候遇到一个需要合并多个predicate条件的问题,下面就是对题的情况.为了方便交流我对case进行了简化,请先看如下代码: using System.Collectio ...
- appium 定位弹出框时报错
今天在做APP自动化时,发现定位弹出框无法定位,无奈,百度去找.发现了一篇不错的博客,故转载过来,供大家参考.后续会验证这个方法的可行性. 本博客转自:http://blog.csdn.net/qq7 ...
- Linux上VNC 启动和关闭
查询vnc的线程: [admin@cn2-uat-esb-01-0001 ~]$ ps -ef|grep vncadmin 19080 21305 0 10:04 pts/2 00:00:00 gre ...
- source insight和vim同时使用
https://blog.csdn.net/wangn222/article/details/72721993 1.Source Insight中,Options->Custom Command ...
- exe自启动的几种方式
1 注册表启动项目RUN (注册路径 HKEY_LOCAL_MACHINE\SOFTWARE\microsoft\Windows\CurrentVersion\Run) 2 计划任务 比较少见这种方式 ...