제출 #165386

#제출 시각아이디문제언어결과실행 시간메모리
165386faremyFish (IOI08_fish)C++14
100 / 100
1095 ms51960 KiB
#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;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...