답안 #165386

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
165386 2019-11-26T18:46:57 Z faremy Fish (IOI08_fish) C++14
100 / 100
1095 ms 51960 KB
#include <iostream>
#include <algorithm>
#include <vector>


struct Fish
{
	int length, jewel;
	bool operator <(const Fish &other) const
	{
		return (other.length < length);
	}
};

const int MAXN = 5e5;
const int LEAVES = 1 << 19;
const int TSIZE = LEAVES << 1;

Fish lake[MAXN];
int ofMaxLength[MAXN];
std::vector<int> ate[MAXN];
int previousPopped[MAXN];

int order[MAXN], revOrder[MAXN];
int combinations[TSIZE];


void update(int pos, int val, int modulo)
{
	pos += LEAVES;
	combinations[pos] = val % modulo;

	for (pos /= 2; pos > 0; pos /= 2)
		combinations[pos] = (combinations[pos * 2] * combinations[pos * 2 + 1]) % modulo;
}

int prod(int left, int right, int modulo)
{
	int res = 1;
	left += LEAVES;
	right += LEAVES;
	
	while (left < right)
	{
		if (left % 2 == 1)
			res = (res * combinations[left++]) % modulo;
		if (right % 2 == 1)
			res = (res * combinations[--right]) % modulo;
		left /= 2;
		right /= 2;
	}

	return res;
}

int search(int left, int right, int value)
{
	if (left == right)
		return right;
	int middle = (left + right) / 2;

	if (lake[ofMaxLength[order[middle]]].length >= value)
		return search(middle + 1, right, value);
	return search(left, middle, value);
}

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

	int fishes, jewelTypes, modulo;
	std::cin >> fishes >> jewelTypes >> modulo;

	for (int iFish = 0; iFish < fishes; iFish++)
	{
		std::cin >> lake[iFish].length >> lake[iFish].jewel;
		lake[iFish].jewel--;
	}

	std::sort(lake, lake + fishes);
	std::fill_n(ofMaxLength, jewelTypes, fishes);

	for (int iFish = 0; iFish < fishes; iFish++)
	{
		int type = lake[iFish].jewel;
		if (ofMaxLength[type] == fishes)
			ofMaxLength[type] = iFish;
	}

	for (int iType = 0; iType < jewelTypes; iType++)
		order[iType] = iType;
	std::sort(order, order + jewelTypes, [](int a, int b) { return (lake[ofMaxLength[a]].length > lake[ofMaxLength[b]].length); });

	for (int iType = 0; iType < jewelTypes; iType++)
	{
		revOrder[order[iType]] = iType;
		ate[iType].emplace_back(0);
	}
	
	std::fill_n(combinations, TSIZE, 1);
	for (int iFish = fishes - 1; iFish > -1; iFish--)
	{
		int type = lake[iFish].jewel;
		ate[type].emplace_back(lake[iFish].length * 2);
		update(revOrder[type], ate[type].size(), modulo);
	}

	int answer = 0, lastFish = 0;
	for (int iType = 0; iType < jewelTypes; iType++)
	{
		int type = order[iType];
		while (lastFish < fishes && lake[lastFish].length * 2 > lake[ofMaxLength[type]].length)
		{
			int removetype = lake[lastFish++].jewel;
			previousPopped[removetype] = ate[removetype].back();
			ate[removetype].pop_back();
			update(revOrder[removetype], ate[removetype].size(), modulo);
		}

		int remove = search(0, iType, previousPopped[type]);
		answer = (answer + prod(remove, iType, modulo) * prod(iType + 1, jewelTypes, modulo)) % modulo;
		answer = (answer + ((ate[type].size() - 1) % modulo) * prod(iType + 1, jewelTypes, modulo)) % modulo;
	}

	std::cout << answer << '\n';

	return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 16248 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 16248 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 23 ms 16376 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 16248 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 16248 KB Output is correct
2 Correct 16 ms 16248 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 16248 KB Output is correct
2 Correct 353 ms 22844 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 16248 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 16292 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 171 ms 19064 KB Output is correct
2 Correct 189 ms 22764 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 24 ms 16376 KB Output is correct
2 Correct 21 ms 16376 KB Output is correct
3 Correct 21 ms 16376 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 223 ms 20564 KB Output is correct
2 Correct 386 ms 29228 KB Output is correct
3 Correct 370 ms 29812 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 364 ms 23288 KB Output is correct
2 Correct 432 ms 30600 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 251 ms 20600 KB Output is correct
2 Correct 438 ms 23024 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 361 ms 22904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 428 ms 23928 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 369 ms 24760 KB Output is correct
2 Correct 623 ms 35064 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 673 ms 28536 KB Output is correct
2 Correct 534 ms 30764 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 555 ms 29432 KB Output is correct
2 Correct 628 ms 35064 KB Output is correct
3 Correct 649 ms 37648 KB Output is correct
4 Correct 681 ms 35096 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 812 ms 31096 KB Output is correct
2 Correct 1070 ms 50900 KB Output is correct
3 Correct 1095 ms 51960 KB Output is correct
4 Correct 1054 ms 47128 KB Output is correct