Codeforces 567D - One-Dimensional Battle Ships - [树状数组+二分]

题目链接:https://codeforces.com/problemset/problem/567/D

 

题意:

在一个 1×n 的网格上,初始摆放着 k 只船,每只船的长度均为 a 个格子,已知所有船之间均不重叠、不触碰。

现在Bob每次询问Alice第 i 个格子上是否存在船,Alice每次都会说不存在,求在第几次询问时,可以确定Alice撒谎了。

 

题解:

对于某次询问一个位置 x 是否有船,假设其属于某个最小的区间 (l,r),其中 l,r 分别是曾经询问过的位置。我们用树状数组配合二分 O(log2n) 寻找出 l,r

那么,可以计算出,(l,r) 区间曾经最多能停放多少船只,而现在变成了两个区间 (l,x)(x,r) 后,又能停放多少船只。

这样一来,最开始我们计算出整个区域 (0,n+1) 最多放多少船只 cur,进而对每次计算都能计算出减少了多少船只,即 cur 会减去一个数,直到某一次询问,使得 cur<k,即代表Alice撒谎了。

 

AC代码:

复制代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,k,a,m;

struct _BIT
{
    int N,C[maxn];
    #define lowbit(x) (x&(-x))
    void init(int n) //初始化共有n个点
    {
        N=n;
        for(int i=1;i<=N;i++) C[i]=0;
    }
    void add(int pos,int val) //在pos点加上val
    {
        while(pos<=N)
        {
            C[pos]+=val;
            pos+=lowbit(pos);
        }
    }
    int ask(int pos) //查询1~pos点的和
    {
        int ret=0;
        while(pos>0)
        {
            ret+=C[pos];
            pos-=lowbit(pos);
        }
        return ret;
    }
}BIT;

int lower(int x)
{
    int l=1, r=BIT.N;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(BIT.ask(mid)<x) l=mid+1;
        else r=mid;
    }
    return l;
}

int upper(int x)
{
    int l=1, r=BIT.N;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(BIT.ask(mid)<=x) l=mid+1;
        else r=mid;
    }
    return l;
}

int main()
{
    cin>>n>>k>>a>>m;

    BIT.init(n+2);
    BIT.add(1,1), BIT.add(n+2,1);
    int cur=(n+1)/(a+1);
    for(int i=1,x;i<=m;i++)
    {
        scanf("%d",&x), x++;

        int tp=BIT.ask(x);
        int l=lower(tp), r=upper(tp);
        int old=(r-l)/(a+1);
        int now=(r-x)/(a+1)+(x-l)/(a+1);
        cur-=old-now;

        if(cur<k)
        {
            printf("%d\n",i);
            return 0;
        }

        BIT.add(x,1);
    }
    printf("-1\n");
}
复制代码

 

posted @   Dilthey  阅读(336)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
历史上的今天:
2018-05-02 CSU 1804 - 有向无环图 - [(类似于)树形DP]
2018-05-02 CSU 1803 - 2016 - [同余]
点击右上角即可分享
微信分享提示