답안 #163553

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
163553 2019-11-13T19:36:41 Z faremy Pyramid Base (IOI08_pyramid_base) C++14
70 / 100
5000 ms 67272 KB
#include <iostream>
#include <algorithm>
#include <vector>


class Interval
{
	int left, right;

public:
	Interval(int l, int r) : left(l), right(r) {}

	bool IsIncludedIn(const Interval &other) const
	{
		return (other.left <= left && right <= other.right);
	}

	bool IsDisjointFrom(const Interval &other) const
	{
		return (other.right <= left || right <= other.left);
	}

	Interval Left() const
	{
		return Interval(left, (left + right) / 2);
	}

	Interval Right() const
	{
		return Interval((left + right) / 2, right);
	}
};

struct Side
{
	Side(int p, int l, int r, long long v) : position(p), covers(l, r), value(v) {}
	int position;
	Interval covers;
	long long value;

	bool operator <(const Side &other) const
	{
		if (position != other.position)
			return (position < other.position);
		return (other.value < value);
	}
};

const int MAXP = 4e5;
const int MAXN = 1e6 + 1;
const long long INFTY = 1e18;

const int LEAVES = 1 << 20;
const int TSIZE = LEAVES << 1;
const Interval ROOTCOVER = { 0, LEAVES };

int left[MAXP], bottom[MAXP];
int right[MAXP], top[MAXP];
long long cost[MAXP];

long long minCovering[TSIZE];
long long covering[TSIZE];
std::vector<Side> obstacleLimits;


void push(int node)
{
	if (node < LEAVES)
	{
		covering[node * 2] += covering[node];
		covering[node * 2 + 1] += covering[node];
	}

	minCovering[node] += covering[node];
	covering[node] = 0;
}

void update(int node, Interval covered, Interval requested, long long value)
{
	push(node);
	if (covered.IsIncludedIn(requested))
	{
		covering[node] = value;
		push(node);
	}
	else if (!covered.IsDisjointFrom(requested))
	{
		update(node * 2, covered.Left(), requested, value);
		update(node * 2 + 1, covered.Right(), requested, value);
		minCovering[node] = std::min(minCovering[node * 2], minCovering[node * 2 + 1]);
	}
}

long long getmin(int node, Interval covered, Interval requested)
{
	push(node);
	if (covered.IsIncludedIn(requested))
		return minCovering[node];
	if (covered.IsDisjointFrom(requested))
		return INFTY;
	return std::min(getmin(node * 2, covered.Left(), requested), getmin(node * 2 + 1, covered.Right(), requested));
}

void buildlimits(int squareSize, int obstacles, int width, int height)
{
	obstacleLimits.clear();
	std::fill_n(minCovering, TSIZE, 0);
	std::fill_n(covering, TSIZE, 0);

	for (int iObst = 0; iObst < obstacles; iObst++)
	{
		int trueLeft = std::max(0, left[iObst] - squareSize);
		int trueBottom = std::max(0, bottom[iObst] - squareSize);
		int trueTop = std::min(height - squareSize + 1, top[iObst]);

		obstacleLimits.emplace_back(trueLeft, trueBottom, trueTop, cost[iObst]);
		if (right[iObst] < width - squareSize + 1)
			obstacleLimits.emplace_back(right[iObst], trueBottom, top[iObst], -cost[iObst]);
	}

	std::sort(obstacleLimits.begin(), obstacleLimits.end());
}

bool isvalidsize(int squareSize, int obstacles, int width, int height, long long budget)
{
	buildlimits(squareSize, obstacles, width, height);
	for (int iLim = 0; iLim < (int)obstacleLimits.size();)
	{
		for (int jLim = iLim; iLim < (int)obstacleLimits.size() && obstacleLimits[iLim].position == obstacleLimits[jLim].position; iLim++)
			update(1, ROOTCOVER, obstacleLimits[iLim].covers, obstacleLimits[iLim].value);
		if (getmin(1, ROOTCOVER, Interval(0, height - squareSize + 1)) <= budget)
			return true;
	}

	return false;
}

int maxsquare(int smallest, int largest, int obstacles, int width, int height, long long budget)
{
	if (smallest == largest)
		return 0;
	int squareSize = (smallest + largest) / 2;

	if (isvalidsize(squareSize, obstacles, width, height, budget))
		return std::max(squareSize, maxsquare(squareSize + 1, largest, obstacles, width, height, budget));
	return maxsquare(smallest, squareSize, obstacles, width, height, budget);
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cout.tie(nullptr);
	std::cin.tie(nullptr);

	int width, height;
	std::cin >> width >> height;

	long long budget; std::cin >> budget;
	int obstacles; std::cin >> obstacles;

	for (int iObst = 0; iObst < obstacles; iObst++)
		std::cin >> left[iObst] >> bottom[iObst] >> right[iObst] >> top[iObst] >> cost[iObst];
	std::cout << maxsquare(1, std::min(width, height) + 1, obstacles, width, height, budget) << '\n';

	return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 55 ms 33272 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 51 ms 33276 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 81 ms 33272 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 95 ms 33348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 130 ms 33360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 141 ms 33356 KB Output is correct
2 Correct 183 ms 33360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 198 ms 33272 KB Output is correct
2 Correct 146 ms 33272 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 136 ms 33656 KB Output is correct
2 Correct 211 ms 33976 KB Output is correct
3 Correct 215 ms 33796 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 472 ms 34508 KB Output is correct
2 Correct 709 ms 34420 KB Output is correct
3 Correct 662 ms 34548 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 561 ms 34548 KB Output is correct
2 Correct 136 ms 35312 KB Output is correct
3 Correct 237 ms 34548 KB Output is correct
4 Correct 809 ms 35312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 899 ms 35568 KB Output is correct
2 Correct 1529 ms 35440 KB Output is correct
3 Correct 490 ms 35572 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 825 ms 35564 KB Output is correct
2 Correct 1906 ms 35564 KB Output is correct
3 Correct 2106 ms 36460 KB Output is correct
4 Correct 1943 ms 36464 KB Output is correct
5 Correct 2087 ms 36464 KB Output is correct
6 Correct 473 ms 36588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5030 ms 50472 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5027 ms 64956 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5031 ms 67272 KB Time limit exceeded
2 Halted 0 ms 0 KB -