Submission #267145

#TimeUsernameProblemLanguageResultExecution timeMemory
267145johuthaRectangles (IOI19_rect)C++17
23 / 100
3081 ms530500 KiB
#include "rect.h"
#include <vector>
#include <iostream>
#include <algorithm>

#define int long long

using namespace std;

struct fenw
{
	int n;
	vector<int> table;

	int query(int k)
	{
		int res = 0;
		for (; k; k -= (k & (-k))) res += table[k];
		return res;
	}

	void update(int k, int v)
	{
		k++;
		for (; k <= n; k += (k & (-k))) table[k] += v;
	}

	fenw(int in) : n(in), table(vector<int>(n + 1)) {}
};

struct bord
{
	int a, b;
	int st, en;

	bool operator<(const bord& ot)
	const {
		if (a != ot.a) return a < ot.a;
		if (b != ot.b) return b < ot.b;
		if (st != ot.st) return st < ot.st;
		return en < ot.en;
	}
};

vector<bord> compress(vector<bord> ip)
{
	vector<bord> res;
	sort(ip.begin(), ip.end());

	for (auto gp : ip)
	{
		if (res.empty() || res.back().a != gp.a || res.back().b != gp.b || res.back().en + 1 != gp.st) res.push_back(gp);
		else res.back().en = gp.en;
	}
	return res;
}

int count(vector<pair<int,int>> a, vector<pair<int,int>> b)
{
	sort(a.begin(), a.end());
	sort(b.begin(), b.end());

	auto b2 = b;
	for (auto &p : b2) swap(p.first, p.second);
	sort(b2.begin(), b2.end());
	for (auto &p : b2) swap(p.first, p.second);

	fenw f(b.size());

	int res = 0;
	int s = 0;
	for (int i = 0; i < (int)a.size(); i++)
	{
		while (s < (int)b2.size() && b2[s].second <= a[i].first)
		{
			int id = lower_bound(b.begin(), b.end(), b2[i]) - b.begin();
			f.update(id, 1);
			s++;
		}
		int lb = lower_bound(b.begin(), b.end(), make_pair(a[i].second, -1000ll)) - b.begin();
		res += f.query(b.size()) - f.query(lb);
	}
	return res;
}

int count_rectangles(vector<vector<signed>> ip)
{
	int r = ip.size();
	int c = ip[0].size();

	vector<bord> hor;
	vector<bord> ver;

	for (int y = 0; y < r; y++)
	{
		vector<pair<int,int>> st;
		for (int x = 0; x < c; x++)
		{
			int sts = st.size();

			for (int i = sts - 1; i >= 0; i--)
			{
				if (st[i].first + 1 < x) hor.push_back(bord{st[i].first, x, y, y});
				if (st[i].second >= ip[y][x]) break;
			}

			while (!st.empty() && st.back().second <= ip[y][x]) st.pop_back();
			st.emplace_back(x, ip[y][x]);
		}
	}

	for (int x = 0; x < c; x++)
	{
		vector<pair<int,int>> st;
		for (int y = 0; y < r; y++)
		{
			int sts = st.size();

			for (int i = sts - 1; i >= 0; i--)
			{
				if (st[i].first + 1 < y) ver.push_back(bord{st[i].first, y, x, x});
				if (st[i].second >= ip[y][x]) break;
			}

			while (!st.empty() && st.back().second <= ip[y][x]) st.pop_back();
			st.emplace_back(y, ip[y][x]);
		}
	}

	hor = compress(hor);
	ver = compress(ver);

	vector<vector<vector<int>>> lw(r, vector<vector<int>>(c));
	vector<vector<vector<int>>> rg(r, vector<vector<int>>(c));

	for (int i = 0; i < (int)hor.size(); i++)
	{
		for (int j = hor[i].st; j <= hor[i].en; j++)
		{
			rg[j][hor[i].b - 1].push_back(i);
		}
	}

	for (int i = 0; i < (int)ver.size(); i++)
	{
		for (int j = ver[i].st; j <= ver[i].en; j++)
		{
			lw[ver[i].b - 1][j].push_back(i);
		}
	}

	int res = 0;

	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			vector<pair<int,int>> nhor;
			vector<pair<int,int>> nver;
			for (auto k : lw[i][j]) nver.emplace_back(j - ver[k].st + 1, ver[k].b - ver[k].a - 1);
			for (auto k : rg[i][j]) nhor.emplace_back(i - hor[k].st + 1, hor[k].b - hor[k].a - 1);
			res += count(nhor, nver);
		}
	}

	return res;
}
#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...