Codeforces Round #291 (Div. 2)D. R2D2 and Droid Army (線段樹+二分)

原題鏈接:

http://codeforces.com/contest/514/problem/D

D. R2D2 and Droid Army
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

An army of n droids is lined up in one row. Each droid is described by m integers a1, a2, ..., am, where ai is the number of details of thei-th type in this droid's mechanism. R2-D2 wants to destroy the sequence of consecutive droids of maximum length. He has m weapons, the i-th weapon can affect all the droids in the army by destroying one detail of the i-th type (if the droid doesn't have details of this type, nothing happens to it).

A droid is considered to be destroyed when all of its details are destroyed. R2-D2 can make at most k shots. How many shots from the weapon of what type should R2-D2 make to destroy the sequence of consecutive droids of maximum length?

Input

The first line contains three integers n, m, k (1 ≤ n ≤ 1051 ≤ m ≤ 50 ≤ k ≤ 109) — the number of droids, the number of detail types and the number of available shots, respectively.

Next n lines follow describing the droids. Each line contains m integers a1, a2, ..., am (0 ≤ ai ≤ 108), where ai is the number of details of the i-th type for the respective robot.

Output

Print m space-separated integers, where the i-th number is the number of shots from the weapon of the i-th type that the robot should make to destroy the subsequence of consecutive droids of the maximum length.

If there are multiple optimal solutions, print any of them.

It is not necessary to make exactly k shots, the number of shots can be less.

Sample test(s)
input
5 2 4
4 0
1 2
2 1
0 2
1 3
output
2 2
input
3 2 4
1 2
1 3
2 2
output
1 3
Note

In the first test the second, third and fourth droids will be destroyed.

In the second test the first and second droids will be destroyed.


題目大意:

n個機器人,每個機器人有m個零件,每個機器人的每個零件有不同的生命值ai,一個人有m個武器,每個武器分別對應攻擊m個零件中的一個,現在他一共可以發k發子彈,他每次用第i個武器發射k枚子彈,所有機器人的第i個零件的生命值都會降i,生命值的最低是0,而已知一個機器人死掉的條件是它的每個零件生命值都爲0,輸出當方案能夠打死連續的數量最多的機器人時,每一種武器分別打出了多少子彈。

思路:

①由於m很小,線段樹維護區間每種零件的最大生命值。

②二分最長連續可以打死的機器人數量,枚舉是否存在長度爲mid的區間滿足總共需要的子彈數小於k。


//交兩次居然就過了有點小驚訝,因爲很少能做出D題,雖然是比賽結束以後,還是比較開心~~不過代碼寫得比較挫


代碼:

#include "stdio.h"
#include "iostream"
#include "string.h"
#include "stdlib.h"
#include "algorithm"
#include "math.h"
using namespace std;

const int MAXN=100010;
int a[MAXN][5];
int n,m,k;

struct NODE{
	int a[5];
	int left,right;
}node[4*MAXN];

struct ANS{
	int a[5];
}ans2;

void PushUp(int t)
{
	for(int i=0;i<m;i++)
	{
		node[t].a[i]=max(node[t<<1].a[i],node[(t<<1)+1].a[i]);
	}
}


void CreatTree(int l,int r,int t)
{
	node[t].left=l;
	node[t].right=r;
	if(l==r)
	{
		for(int i=0;i<m;i++)
			node[t].a[i]=a[l][i];
		return;
	}
	CreatTree(l,(l+r)/2,t<<1);
	CreatTree((l+r)/2+1,r,(t<<1)+1);
	PushUp(t);
}

struct ANS max2(struct ANS a1,struct ANS a2)
{
	struct ANS ans;
	for(int i=0;i<m;i++)
		ans.a[i]=max(a1.a[i],a2.a[i]);
	return ans;
}

struct ANS Query(int l,int r,int t)
{
	ANS ans;
	for(int i=0;i<m;i++)
		ans.a[i]=0;
	if(node[t].left==l&&node[t].right==r)
	{
		for(int i=0;i<m;i++)
			ans.a[i]=node[t].a[i];
		return ans;
	}
	int w=t<<1;
	if(l<=node[w].right)
	{
		if(r<=node[w].right)
			ans=max2(Query(l,r,w),ans);
		else
			ans=max2(Query(l,node[w].right,w),ans);
	}
	w+=1;
	if(r>=node[w].left)
	{
		if(l>=node[w].left)
			ans=max2(Query(l,r,w),ans);
		else
			ans=max2(Query(node[w].left,r,w),ans);
	}
	return ans;
}

int fun(int mid)
{
	for(int i=1;i<=n-mid+1;i++)
	{
		ans2=Query(i,i+mid-1,1);
		int sum=0;
		for(int j=0;j<m;j++)
		{
			sum+=ans2.a[j];
		}
		if(sum<=k)
			return 1;
	}
	return 0;
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++)
		for(int j=0;j<m;j++)
			scanf("%d",&a[i][j]);
	CreatTree(1,n,1);
	long long r,l,mid;
	l=1;
	r=n;
	struct ANS ans3;
	for(int i=0;i<m;i++)
		ans3.a[i]=0;
	while(l<=r)
	{
		mid=(l+r)/2;
		if(fun(mid))
		{
			ans3=ans2;
			l=mid+1;
		}
		else
			r=mid-1;
	}
	for(int i=0;i<m;i++)
		printf("%d ",ans3.a[i]);
	printf("\n");
	return 0;
}


發佈了66 篇原創文章 · 獲贊 20 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章