Submission #146224

#TimeUsernameProblemLanguageResultExecution timeMemory
146224SortingRectangles (IOI19_rect)C++14
100 / 100
4963 ms470028 KiB
#include "rect.h"
#include <bits/stdc++.h>

using namespace  std;

const int MAXN = 2507;
const int inf = 1e9;

inline int fast_min(int lvalue, int rvalue){
	return ((lvalue < rvalue) ? lvalue : rvalue);
}

inline int fast_max(int lvalue, int rvalue){
	return ((lvalue > rvalue) ? lvalue : rvalue);
}

struct b_str{
	int l, r, u, d;

	b_str(){}
};


b_str b[MAXN][MAXN];

struct segment_tree{
	int mn[2 * MAXN];
	char type;
	int val;
	int sz;

	segment_tree(){}

	void init(char type, int val, int sz){
		this->type = type;
		this->val = val;
		this->sz = sz;
		
		for(int i = 0; i < sz; ++i){
			int idx = i + sz;

			switch(type){
			case 'l':
				mn[idx] = b[i][val].l;
				break;
			case 'r':
				mn[idx] = b[i][val].r;
				break;
			case 'u':
				mn[idx] = b[val][i].u;
				break;
			case 'd':
				mn[idx] = b[val][i].d;
				break;
			}
		}
		for(int i = sz - 1; i > 0; --i){
			mn[i] = fast_min(mn[i << 1], mn[(i << 1) | 1]);
		}
	}

	int query(int l, int r){
		++r;

		int resl = inf, resr = inf;

		for(l += sz, r += sz; l < r; l >>= 1, r >>= 1){
            if(l & 1){
            	resl = fast_min(resl, mn[l++]);
            }
            if(r & 1){
            	resr = fast_min(mn[--r], resr);
            }
        }

        return fast_min(resl, resr);
	}
};

struct rect{
	int x1, y1, x2, y2;

	rect(){}

	friend bool operator<(rect lvalue, rect rvalue){
		if(lvalue.x1 != rvalue.x1){
			return lvalue.x1 < rvalue.x1;
		}
		if(lvalue.x2 != rvalue.x2){
			return lvalue.x2 < rvalue.x2;
		}
		if(lvalue.y1 != rvalue.y1){
			return lvalue.y1 < rvalue.y1;
		}

		return lvalue.y2 < rvalue.y2;
	}
};

rect v[MAXN * MAXN];
segment_tree st_l[MAXN], st_r[MAXN], st_u[MAXN], st_d[MAXN];
int a[MAXN][MAXN], n, m;

bool check(int x1, int y1, int x2, int y2){
	//cout << x1 << " " << y1 << " " << x2 << " " << y2 << endl;

	int lvalue = st_l[y2 + 1].query(x1, x2);
	int rvalue = st_r[y1 - 1].query(x1, x2);
	int uvalue = st_u[x2 + 1].query(y1, y2);
	int dvalue = st_d[x1 - 1].query(y1, y2);

	if(fast_min(lvalue, rvalue) < y2 - y1 + 2){
		return false;
	}
	if(fast_min(uvalue, dvalue) < x2 - x1 + 2){
		return false;
	}

	return true;
}

stack<int> st;

long long count_rectangles(vector<vector<int> > _a) {
	n = _a.size();
	m = _a[0].size();

	for(int i = 0; i < n; ++i){
		for(int j = 0; j < m; ++j){
			a[i][j] = _a[i][j];
		}
	}

	for(int i = 0; i < n; ++i){
		st.push(0);
		for(int j = 1; j < m; ++j){
			while(!st.empty() && a[i][j] >= a[i][st.top()]){
				b[i][st.top()].r = j - st.top();
				st.pop();
			}
			st.push(j);
		}
		while(!st.empty()){
			b[i][st.top()].r = m - st.top();
			st.pop();
		}
	}

	for(int i = 0; i < n; ++i){
		st.push(m - 1);
		for(int j = m - 2 ; j >= 0; --j){
			while(!st.empty() && a[i][j] >= a[i][st.top()]){
				b[i][st.top()].l = st.top() - j;
				st.pop();
			}
			st.push(j);
		}
		while(!st.empty()){
			b[i][st.top()].l = st.top() + 1;
			st.pop();
		}
	}

	for(int i = 0; i < m; ++i){
		st.push(0);
		for(int j = 1; j < n; ++j){
			while(!st.empty() && a[j][i] >= a[st.top()][i]){
				b[st.top()][i].d = j - st.top();
				st.pop();
			}
			st.push(j);
		}
		while(!st.empty()){
			b[st.top()][i].d = n - st.top();
			st.pop();
		}
	}

	for(int i = 0; i < m; ++i){
		st.push(n - 1);
		for(int j = n - 2; j >= 0; --j){
			while(!st.empty() && a[j][i] >= a[st.top()][i]){
				b[st.top()][i].u = st.top() - j;
				st.pop();
			}
			st.push(j);
		}
		while(!st.empty()){
			b[st.top()][i].u = st.top() + 1;
			st.pop();
		}
	}

	for(int i = 0; i < n; ++i){
		st_u[i].init('u', i, m);
		st_d[i].init('d', i, m);
	}
	for(int i = 0; i < m; ++i){
		st_l[i].init('l', i, n);
		st_r[i].init('r', i, n);
	}

	for(int i = 0; i < n; ++i){
		st.push(0);
		for(int j = 1; j < m; ++j){
			while(!st.empty() && a[i][j] > a[i][st.top()]){
				b[i][st.top()].r = j - st.top();
				st.pop();
			}
			st.push(j);
		}
		while(!st.empty()){
			b[i][st.top()].r = m - st.top();
			st.pop();
		}
	}

	for(int i = 0; i < n; ++i){
		st.push(m - 1);
		for(int j = m - 2 ; j >= 0; --j){
			while(!st.empty() && a[i][j] > a[i][st.top()]){
				b[i][st.top()].l = st.top() - j;
				st.pop();
			}
			st.push(j);
		}
		while(!st.empty()){
			b[i][st.top()].l = st.top() + 1;
			st.pop();
		}
	}

	for(int i = 0; i < m; ++i){
		st.push(0);
		for(int j = 1; j < n; ++j){
			while(!st.empty() && a[j][i] > a[st.top()][i]){
				b[st.top()][i].d = j - st.top();
				st.pop();
			}
			st.push(j);
		}
		while(!st.empty()){
			b[st.top()][i].d = n - st.top();
			st.pop();
		}
	}

	for(int i = 0; i < m; ++i){
		st.push(n - 1);
		for(int j = n - 2; j >= 0; --j){
			while(!st.empty() && a[j][i] > a[st.top()][i]){
				b[st.top()][i].u = st.top() - j;
				st.pop();
			}
			st.push(j);
		}
		while(!st.empty()){
			b[st.top()][i].u = st.top() + 1;
			st.pop();
		}
	}

	long long ans = 0;
	int cnt = 0;

	for(int i = 1; i < n - 1; ++i){
		for(int j = 1; j < m - 1; ++j){
			rect r;

			r.x1 = fast_min(n - 2, fast_max(1, i - b[i][j].u + 1));
			r.x2 = fast_min(n - 2, fast_max(1, i + b[i][j].d - 1));
			r.y1 = fast_min(m - 2, fast_max(1, j - b[i][j].l + 1));
			r.y2 = fast_min(m - 2, fast_max(1, j + b[i][j].r - 1));

			//cout << i << " " << j << " - " << r.x1 << " " << r.y1 << " " << r.x2 << " " << r.y2 << endl;

			v[cnt++] = r;
		}
	}

	sort(v, v + cnt);

	for(int i = 0; i < cnt; ++i){
		if(i != 0 && v[i - 1].x1 == v[i].x1 && v[i - 1].y1 == v[i].y1 && v[i - 1].x2 == v[i].x2 && v[i - 1].y2 == v[i].y2){
			continue;
		}
		ans += check(v[i].x1, v[i].y1, v[i].x2, v[i].y2);
	}

	return ans;
}
/*
6 5
4 8 7 5 6
7 4 10 3 5
9 7 20 14 2
9 14 7 3 6
5 7 5 2 7
4 5 13 5 6
*/
#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...