CF514D R2D2 and Droid Army(二分,ST表)
传送门
解题思路
直接二分能干掉的人数,然后check函数枚举所有区间,因为 m 很小,所以可以用 m 个ST表预处理每个区间对应每个属性的最大值。
一是需要注意二分的写法,而是注意check(0)时候的特判。
AC代码
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
#include<ctime>
#include<stack>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!(c>='0'&&c<='9')) {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
const int maxn=2e5+5;
int n,m,k,a[maxn][6],d[6][maxn][20],ans[6],res[6];
int query(int id,int l,int r){
int x=log2(r-l+1);
return max(d[id][l][x],d[id][r-(1<<x)+1][x]);
}
bool check(int x){
if(x==0) return 1;
for(int i=1;i<=n-x+1;i++){
int r=i+x-1,sum=0;
for(int j=1;j<=m;j++){
res[j]=query(j,i,r);
sum+=res[j];
}
if(sum<=k){
for(int j=1;j<=m;j++) ans[j]=res[j];
return 1;
}
}
return 0;
}
int main()
{
n=read(),m=read(),k=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
d[j][i][0]=a[i][j]=read();
}
}
for(int id=1;id<=m;id++){
for(int len=1;(1<<len)<=n;len++){
for(int i=1;i+(1<<len)-1<=n;i++){
d[id][i][len]=max(d[id][i][len-1],d[id][i+(1<<(len-1))][len-1]);
}
}
}
int l=0,r=n;
while(l<=r){
int mid=(l+r)/2;
if(check(mid)) l=mid+1;
else r=mid-1;
}
for(int i=1;i<=m;i++) cout<<ans[i]<<' ';
return 0;
}
作者:尹昱钦
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端