【codeforces 514D】R2D2 and Droid Army
【题目链接】:http://codeforces.com/contest/514/problem/D
【题意】
给你每个机器人的m种属性p1..pm
然后r2d2每次可以选择m种属性中的一种,进行一次攻击;
攻击过后每个机器人的该种属性都减少1;
可以最多攻击k次;
机器人只有m种属性都变为0之后才死掉;
然后问你如何分配这k次攻击,每次攻击时选择的属性;
使得连续的死掉的机器人的区间长度最长;
【题解】
对于选择的一个区间[l..r]
如果要使得这个区间的机器人全都死掉;
则需要攻击的次数就为
因为某一种属性的在这个区间的最大值如果都变成0了,那么其他的也就变成0了;
则问题就是RMQ问题了;
然后写个二分;
枚举左端点,二分右端点;
上面那个值小于等于k就符合,增大右端点
否则减小右端点
写了个ST算法的。没写线段树
【Number Of WA】
0
【完整代码】
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define ps push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x)
#define ms(x,y) memset(x,y,sizeof x)
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 1e5+100;
const int M = 5+3;
const int maxpow = 20;
int n,m,k;
int a[M][N],two[maxpow];
int f[M][N][maxpow],need[N];
int ans[M],len,temp[M];
int main()
{
//freopen("F:\\rush.txt","r",stdin);
rei(n),rei(m),rei(k);
rep1(i,1,n)
rep1(j,1,m)
rei(a[j][i]);
two[0] = 1;
rep1(i,1,17)
two[i] = two[i-1]*2;
need[1] = 0;
int now = 1;
rep1(i,2,100000)
if (i==two[now])
{
now++;
need[i]=need[i-1]+1;
}
else
need[i]=need[i-1];
rep1(i,1,m)
rep1(j,1,n)
f[i][j][0] = a[i][j];
rep1(k,1,m)
{
for (int l = 1;two[l]<=n;l++)
{
rep1(i,1,n)
{
if (i+two[l]-1>n) break;
int j = i+two[l]-1;
f[k][i][l] = max(f[k][i][l-1],f[k][j-two[l-1]+1][l-1]);
}
}
}
rep1(i,1,n)
{
int l = i,r = n;
while (l <= r)
{
int mid = (l+r)>>1;
//i..mid
int cd = need[mid-i+1],cost = 0;
rep1(j,1,m)
{
temp[j] = max(f[j][i][cd],f[j][mid-two[cd]+1][cd]);
cost+=temp[j];
}
if (cost<=k)
{
if (mid-i+1>len)
{
rep1(j,1,m)
ans[j] = temp[j];
len = mid-i+1;
}
l = mid+1;
}
else
r = mid-1;
}
}
rep1(i,1,m)
printf("%d ",ans[i]);
//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}