2019牛客暑假多校训练赛第十场F Popping Balloons(优先队列维护)

题目链接:https://ac.nowcoder.com/acm/contest/890/F

题意:给定n,r,在一个1e5*1e5的方格图中有n个方格里面有气球,现在让竖向打三枪横向打三枪,必须满足三枪打的位置是x,x+r,x+r+r,问最多能打破多少气球,一枪打一行或列。

数据范围:1<=n,r,x,y<=1e5

 

思路:开一个优先队列从大到小排,对于每个气球可以由y,y-r,y-r-r三个位置开始的第一枪打到,那么对于这三个位置开枪的贡献就可以+1,处理好y以后就可以从0到1e5枚举x坐标打竖着的三枪,对于每个位置枚举时要把x,x+r,x+r+r这三列上的气球在之前处理的y的位置上减去,然后从优先队列里找到最大的y值就好了,最后再把减去的还回去。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m,t,r;
vector<int>G[N*3];
priority_queue<pair<int,int> >Q;
int f[N*3];
void ins(int y,int val){
    if(y>=0){
        f[y]+=val;
        Q.push(make_pair(f[y],y));
    }
}
int gettop(){
    pair<int,int>u=Q.top();
    while(u.first!=f[u.second]){
        Q.pop();
        u=Q.top();
    }
    return u.first;
}
int main(){
    scanf("%d%d",&n,&r);
    int x,y;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        G[x].push_back(y);
        ins(y,1);
        ins(y-r,1);
        ins(y-r-r,1);
    }
    int ans=0;
    for(int i=0;i<=100000;i++){
        int len=G[i].size();
        for(int j=0;j<len;j++)ins(G[i][j],-1),ins(G[i][j]-r,-1),ins(G[i][j]-r-r,-1);
        len=G[i+r].size();
        for(int j=0;j<len;j++)ins(G[i+r][j],-1),ins(G[i+r][j]-r,-1),ins(G[i+r][j]-r-r,-1);
        len=G[i+r+r].size();
        for(int j=0;j<len;j++)ins(G[i+r+r][j],-1),ins(G[i+r+r][j]-r,-1),ins(G[i+r+r][j]-r-r,-1);
        ans=max(ans,int(G[i].size()+G[i+r].size()+G[i+r+r].size()+gettop()));
        len=G[i].size();
        for(int j=0;j<len;j++)ins(G[i][j],1),ins(G[i][j]-r,1),ins(G[i][j]-r-r,1);
        len=G[i+r].size();
        for(int j=0;j<len;j++)ins(G[i+r][j],1),ins(G[i+r][j]-r,1),ins(G[i+r][j]-r-r,1);
        len=G[i+r+r].size();
        for(int j=0;j<len;j++)ins(G[i+r+r][j],1),ins(G[i+r+r][j]-r,1),ins(G[i+r+r][j]-r-r,1);
    }
    printf("%d\n",ans);
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值