题目链接:https://codeforces.com/contest/514/problem/D
题目大意:给n个机器人,每个机器人有m个属性,可以针对每个属性都发出相应的攻击,要求总攻击<=k,而且连续被摧毁的机器人数最多,每个机器人所有的属性都变为0时视为被摧毁。
题目思路:建五棵线段树,分别维护各个属性,然后二分枚举连续机器人个数,暴力求解该人数情况下是否能够符合题意。
以下是代码:
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
const int MAXN = 1e5+5;
int n,m,k,pos;
int a[MAXN][5];
struct node{
int l,r,val;
}Tree[MAXN<<2][5];
void build(int rt,int l,int r,int num){
Tree[rt][num].l=l,Tree[rt][num].r=r;
if(l==r){
Tree[rt][num].val = a[l][num];
return;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid,num);
build(rt<<1|1,mid+1,r,num);
Tree[rt][num].val=max(Tree[rt<<1][num].val,Tree[rt<<1|1][num].val);
}
int query(int rt, int l, int r, int num){
if(Tree[rt][num].l>=l&&Tree[rt][num].r<=r){
return Tree[rt][num].val;
}
int mid=(Tree[rt][num].l+Tree[rt][num].r)>>1;
int maxx=0;
if(l<=mid)maxx=max(query(rt<<1,l,r,num),maxx);
if(r>mid)maxx=max(query(rt<<1|1,l,r,num),maxx);
return maxx;
}
bool check(int x){
rep(i,1,n-x+1){
int temp=0;
rep(j,0,m-1){
temp += query(1,i,i+x-1,j);
}
if(temp<=k){
pos=i;
return true;
}
}
return false;
}
int main(){
while(~scanf("%d%d%d",&n,&m,&k)){
rep(i,1,n){
rep(j,0,m-1){
scanf("%d",&a[i][j]);
}
}
rep(i,0,m-1)build(1,1,n,i);
int l=0,r=n,ans=-1;
while(l<=r){
int mid = (l+r)>>1;
if(check(mid)){
l = mid + 1;
ans = mid;
}
else{
r = mid - 1;
}
}
rep(i,0,m-1){
printf("%d ",query(1,pos,pos+ans-1,i));
}
printf("\n");
}
return 0;
}