题意:

给定一个稀疏矩阵,里面有若干个气球,让你横着开三枪,竖着开三枪,问最多能打爆多少气球,要求相同方向,相邻两枪必须间隔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 线段树维护稀疏矩阵的更多相关文章

  1. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  2. 2019年牛客多校第四场 B题xor(线段树+线性基交)

    题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...

  3. 2019牛客多校第四场C-sequence(单调栈+线段树)

    sequence 题目传送门 解题思路 用单调栈求出每个a[i]作为最小值的最大范围.对于每个a[i],我们都要乘以一个以a[i]为区间内最小值的对应的b的区间和s,如果a[i] > 0,则s要 ...

  4. 牛客多校第七场 C Governing sand 线段树

    题意: 有一个树林,树林中不同种类的树有不同的数量,高度,砍伐它们的价格.现在要求砍掉一些树,使得高度最高的树占剩下的树的总数的一半以上,求最小花费. 题解: 用线段树维护不同种类树的信息,叶子节点从 ...

  5. 牛客多校第三场 F Planting Trees

    牛客多校第三场 F Planting Trees 题意: 求矩阵内最大值减最小值大于k的最大子矩阵的面积 题解: 矩阵压缩的技巧 因为对于我们有用的信息只有这个矩阵内的最大值和最小值 所以我们可以将一 ...

  6. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  7. 牛客多校第五场 F take

    链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 题目描述 Kanade has n boxes , the i-th box has p[i] ...

  8. 牛客多校第四场 F Beautiful Garden

    链接:https://www.nowcoder.com/acm/contest/142/F来源:牛客网 题目描述 There's a beautiful garden whose size is n ...

  9. 牛客多校第十场 A Rikka with Lowbit 线段树

    链接:https://www.nowcoder.com/acm/contest/148/A来源:牛客网 题目描述 Today, Rikka is going to learn how to use B ...

随机推荐

  1. 转载 如何理解API,API 是如何工作的

    本文转载于https://blog.csdn.net/cumtdeyurenjie/article/details/80211896 感谢作者 仁杰兄 大家可能最近经常听到 API 这个概念,那什么是 ...

  2. 离线+生成树+并查集——cf1213G

    #include<bits/stdc++.h> using namespace std; #define N 200005 #define ll long long struct Edge ...

  3. 行内元素与块级元素的区别,行内块级元素在IE8-的兼容性

    行内元素与块级元素的区别 行内元素最好不要包裹块级元素,但是块级元素可以任意的包裹行内元素 行内元素如果其上一个元素也是行内元素,则他们会分布在统一水平线上,即在一行上排列,块级元素不论上一个元素是行 ...

  4. CSS:教程

    ylbtech-CSS:教程 1.返回顶部 1. CSS 教程 通过使用 CSS 我们可以大大提升网页开发的工作效率! 在我们的 CSS 教程中,您会学到如何使用 CSS 同时控制多重网页的样式和布局 ...

  5. svn启动服务

    bin目录添加到环境变量classpathsvn --version 查看版本svnadmin create D:\\xx 创建本地中央仓库启动svn服务 cmd命令 svnserve -d -r D ...

  6. flink中对于window和watermark的一些理解

    package com.chenxiang.flink.demo; import java.io.IOException; import java.net.ServerSocket; import j ...

  7. Netty 相关目录

    Netty 相关目录 Netty 源码学习--客户端流程分析 Netty 源码学习--服务端流程分析 Netty 源码分析--ChannelPipeline Netty 源码学习--EventLoop ...

  8. explain分析sql语句执行效率

    Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好的优 ...

  9. testNG官方文档翻译-2 注解

    这里是一份TestNG中的可用注解及其属性的概述. 一.用于一个TestNG类的信息配置的注解: @BeforeSuite:被BeforeSuite注解的方法将在其所在suite中的所有test运行之 ...

  10. opencv——常见的操作

    一 图像阈值处理 准备一张灰度图像 阈值处理通常是设定一个阈值,让图片的所有像素点的值与其比较做出一系列的操作. 在opencv常用的阈值处理函数有五种,分别是THRESH_BINARY.THRESH ...