概述
题意:
n个机器人,有m个属性,每个机器人的属性值a1-am已经给出,我有一把枪,也有m个属性,若把枪调为第i种属性,每打一枪可以让这n个机器人的属性i减1。当一个机器人的所有属性值都<=0时,该机器人死亡。我现在可以打k枪,问怎么打能让连续的死亡的机器人的长度最大。输出为属性为1-m,每种属性打几枪。可以不用打满k枪。
分析:
二分连续死亡的值,判定使用ST,nlogn的预处理,O(1)查询区间最值。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Inf 0x3f3f3f3f
#define PI
acos(-1.0)
using namespace std;
typedef long long ll;
const double eps = 1e-6;
const int N = 1e5+5;
const int mod=1e9+7;
ll n,m,k;
ll a[N][6];
ll ans[6];
ll f[N][20][6];
void ST_prework()
{
for(int k=1;k<=m;k++)
{
for(int i=1;i<=n;i++)
f[i][0][k]=a[i][k];
int t=log(n)/log(2)+1;
for(int j=1;j<t;j++)
{
for(int i=1;i<=n-(1<<j)+1;i++)
{
f[i][j][k]=max(f[i][j-1][k],f[i+(1<<(j-1))][j-1][k]);
}
}
}
}
int ST_query(int l,int r,int k)
{
int j=log(r-l+1)/log(2);
return max(f[l][j][k],f[r-(1<<j)+1][j][k]);
}
bool ok(ll x)
{
for(int s=1;s+x-1<=n;s++)
{
ll e=s+x-1;
ll last=k;
for(int j=1;j<=m;j++)
{
last-=ST_query(s,e,j);
}
if(last>=0)
return true;
}
return false;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
scanf("%lld %lld %lld",&n,&m,&k);
for(int i=1;i<=n;i++)
{
a[i][0]=0;
for(int j=1;j<=m;j++)
{
scanf("%lld",&a[i][j]);
}
}
ST_prework();
ll l,r;
l=0;r=n;
while(l<=r)
{
ll mid=(l+r)/2;
if(ok(mid))
l=mid+1;
else
r=mid-1;
}
l-=1;
for(int s=1;s+l-1<=n;s++)
{
ll e=s+l-1;
ll last=k;
for(int j=1;j<=m;j++)
{
last-=ST_query(s,e,j);
ans[j]=ST_query(s,e,j);
}
if(last>=0)
break;
}
// cout<<l<<endl;
for(int i=1;i<=m;i++)
printf("%lld%c",ans[i],i==m?'n':' ');
return 0;
}
最后
以上就是年轻钻石为你收集整理的CodeForces - 514D(ST+二分)的全部内容,希望文章能够帮你解决CodeForces - 514D(ST+二分)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复