Codeforces 567D - One-Dimensional Battle Ships - [树状数组+二分]
题目链接:https://codeforces.com/problemset/problem/567/D
题意:
在一个 的网格上,初始摆放着 只船,每只船的长度均为 个格子,已知所有船之间均不重叠、不触碰。
现在Bob每次询问Alice第 个格子上是否存在船,Alice每次都会说不存在,求在第几次询问时,可以确定Alice撒谎了。
题解:
对于某次询问一个位置 是否有船,假设其属于某个最小的区间 ,其中 分别是曾经询问过的位置。我们用树状数组配合二分 寻找出 。
那么,可以计算出, 区间曾经最多能停放多少船只,而现在变成了两个区间 和 后,又能停放多少船只。
这样一来,最开始我们计算出整个区域 最多放多少船只 ,进而对每次计算都能计算出减少了多少船只,即 会减去一个数,直到某一次询问,使得 ,即代表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"); }
转载请注明出处:https://dilthey.cnblogs.com/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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 - [同余]