제출 #1082166

#제출 시각아이디문제언어결과실행 시간메모리
1082166aykhnRectangles (IOI19_rect)C++17
59 / 100
5064 ms775396 KiB
#include "rect.h"
#include <bits/stdc++.h>

using namespace std;

#define int long long

const int MX = 7e6 + 5;

struct BIT
{
	int n;
	vector<int> ft;
	void init(int N)
	{
		n = N + 5;
		ft.assign(n + 5, 0);
	}
	void add(int pos, int val)
	{
		for (pos = pos + 1; pos <= n; pos += pos & -pos) ft[pos] += val;
	}
	int get(int pos, int res = 0)
	{
		for (pos = pos + 1; pos > 0; pos -= pos & -pos) res += ft[pos];
		return res;
	}
};

vector<array<int, 2>> ind[MX];

long long count_rectangles(vector<vector<int32_t>> a) 
{
	int n = a.size(), m = a[0].size();
	set<int> r[n], c[m];
	vector<int> v;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			ind[a[i][j]].push_back({i, j});
		}
	}
	for (int i = 0; i < n; i++) r[i].insert(-1), r[i].insert(m);
	for (int i = 0; i < m; i++) c[i].insert(-1), c[i].insert(n);
	set<array<int, 3>> r1, c1;
	for (int i = MX - 1; i >= 0; i--)
	{
		for (array<int, 2> &x : ind[i])
		{
			int L = *prev(r[x[0]].lower_bound(x[1])), R = *r[x[0]].lower_bound(x[1]);
			if (!(L < 0 || R >= m)) r1.insert({x[0], L + 1, R - 1});
			L = *prev(c[x[1]].lower_bound(x[0])), R = *c[x[1]].lower_bound(x[0]);
			if (!(L < 0 || R >= n)) c1.insert({x[1], L + 1, R - 1});
		}
		for (array<int, 2> &x : ind[i])
		{
			r[x[0]].insert(x[1]);
			c[x[1]].insert(x[0]);
		}
	}
	BIT ft;
	ft.init(max(n, m));
	vector<int> addR[n][m], addC[n][m];
	for (array<int, 3> i : r1) addR[i[0]][i[2]].push_back(i[1]);
	for (array<int, 3> i : c1) addC[i[2]][i[0]].push_back(i[1]);
	int res = 0;
	map<array<int, 2>, int> mpC, nwC, mpR, nwR;
	vector<array<int, 2>> v1, v2;
	for (int j = 0; j < m; j++)
	{
		nwC.clear();
		for (int i = 0; i < n; i++)
		{
			nwR.clear(), v1.clear(), v2.clear();
			for (int &x : addR[i][j])
			{
				int x1 = j - x + 1, y1 = (mpR.find({x, j}) != mpR.end() ? mpR[{x, j}] : 0) + 1;
				v1.push_back({x1, y1});
			}
			for (int &y : addC[i][j])
			{
				int x2 = i - y + 1, y2 = (mpC.find({y, i}) != mpC.end() ? mpC[{y, i}] : 0) + 1;
				v2.push_back({x2, y2});
			}
			sort(v1.begin(), v1.end(), [&](const array<int, 2> &x, const array<int, 2> &y)
			{
				return x[1] < y[1];
			});
			sort(v2.begin(), v2.end(), [&](const array<int, 2> &x, const array<int, 2> &y)
			{
				return x[0] < y[0];
			});
			int y = 0;
			for (int x = 0; x < v1.size(); x++)
			{
				while (y < v2.size() && v1[x][1] >= v2[y][0])
				{
					ft.add(v2[y][1], 1);
					y++;
				}
				res += ft.get(max(n, m)) - ft.get(v1[x][0] - 1);
			}
			for (int x = 0; x < y; x++) ft.add(v2[x][1], -1);
			for (int &x : addR[i][j]) nwR[{x, j}] = mpR[{x, j}] + 1;
			for (int &y : addC[i][j]) nwC[{y, i}] = mpC[{y, i}] + 1;
			mpR = nwR;
		}
		mpC = nwC;
	}
	return res;
}

컴파일 시 표준 에러 (stderr) 메시지

rect.cpp: In function 'long long int count_rectangles(std::vector<std::vector<int> >)':
rect.cpp:95:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::array<long long int, 2> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   95 |    for (int x = 0; x < v1.size(); x++)
      |                    ~~^~~~~~~~~~~
rect.cpp:97:14: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::array<long long int, 2> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   97 |     while (y < v2.size() && v1[x][1] >= v2[y][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...