Submission #155496

#TimeUsernameProblemLanguageResultExecution timeMemory
155496vanicRectangles (IOI19_rect)C++14
18 / 100
5004 ms630676 KiB
#include "rect.h"
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <unordered_map>

using namespace std;

typedef long long ll;
const int maxn=2505;

int n, m;
int l[maxn][maxn];
vector < int > r[maxn][maxn], c[maxn][maxn];
pair < int, int > red[maxn][maxn], stup[maxn][maxn];
unordered_map < ll, bool > bio, bio2, bio3;

inline ll hashiraj(ll a, ll b, ll c, ll d){
	return a*maxn*maxn*maxn+b*maxn*maxn+c*maxn+d;
}

void upd1(int x, bool p){
	deque < pair < int, int > > q;
	int sz;
	sz=m;
	for(int i=0; i<sz; i++){
		while(!q.empty() && q.back().first<=l[x][i]){
			q.pop_back();
		}
		if(!q.empty()){
			red[x][i].first=q.back().second+1;
		}
		else{
			red[x][i].first=0;
		}
		q.push_back(make_pair(l[x][i], i));
	}
	while(!q.empty()){
		q.pop_back();
	}
	for(int i=sz-1; i>-1; i--){
		while(!q.empty() && q.back().first<=l[x][i]){
			q.pop_back();
		}
		if(!q.empty()){
			red[x][i].second=q.back().second-1;
			if(!bio2[hashiraj(0, red[x][i].first, red[x][i].second, x)]){
				bio2[hashiraj(0, red[x][i].first, red[x][i].second, x)]=1;
				r[red[x][i].first][red[x][i].second].push_back(x);
			}
		}
		else{
			red[x][i].second=sz-1;
			if(!bio2[hashiraj(0, red[x][i].first, red[x][i].second, x)]){
				bio2[hashiraj(0, red[x][i].first, red[x][i].second, x)]=1;
				r[red[x][i].first][red[x][i].second].push_back(x);
			}
		}
		q.push_back(make_pair(l[x][i], i));
	}
}

void upd2(int x, bool p){
	deque < pair < int, int > > q;
	int sz;
	sz=n;
	for(int i=0; i<sz; i++){
		while(!q.empty() && q.back().first<=l[i][x]){
			q.pop_back();
		}
		if(!q.empty()){
			stup[i][x].first=q.back().second+1;
		}
		else{
			stup[i][x].first=0;
		}
		q.push_back(make_pair(l[i][x], i));
	}
	while(!q.empty()){
		q.pop_back();
	}
	for(int i=sz-1; i>-1; i--){
		while(!q.empty() && q.back().first<=l[i][x]){
			q.pop_back();
		}
		if(!q.empty()){
			stup[i][x].second=q.back().second-1;
			if(!bio3[hashiraj(0, stup[i][x].first, stup[i][x].second, x)]){
				bio3[hashiraj(0, stup[i][x].first, stup[i][x].second, x)]=1;
				c[stup[i][x].first][stup[i][x].second].push_back(x);
			}
		}
		else{
			stup[i][x].second=sz-1;
			if(!bio3[hashiraj(0, stup[i][x].first, stup[i][x].second, x)]){
				bio3[hashiraj(0, stup[i][x].first, stup[i][x].second, x)]=1;
				c[stup[i][x].first][stup[i][x].second].push_back(x);
			}
		}
		q.push_back(make_pair(l[i][x], i));
	}
}


int binary(int x, vector < int > &l){
	int lo=0, hi=l.size()-1, mid;
	while(lo<hi){
		mid=(lo+hi)/2;
		if(l[mid]<x){
			lo=mid+1;
		}
		else{
			hi=mid;
		}
	}
	return lo;
}

bool provjeri(int x, int y){
	int r1, r2, c1, c2;
	r1=red[x][y].first;
	r2=red[x][y].second;
	c1=stup[x][y].first;
	c2=stup[x][y].second;
	if(r1==0 || c1==0 || r2==m-1 || c2==n-1){
		return 0;
	}
	int pos1=binary(c1, r[r1][r2]);
	int pos2=binary(r1, c[c1][c2]);
/*	printf("novi\n");
	printf("%d %d\n", x, y);
	printf("%d %d\n", r1, r2);
	printf("%d %d\n", c1, c2);
	printf("%d %d\n", pos1, pos2);
	for(int i=0; i<r[r1][r2].size(); i++){
		printf("%d ", r[r1][r2][i]);
	}
	printf("\n");
	for(int i=0; i<c[c1][c2].size(); i++){
		printf("%d ", c[c1][c2][i]);
	}
	printf("\n");*/
	if(r[r1][r2][pos1]==c1 && r[r1][r2].size()-pos1-c2+c1-1>=0 && r[r1][r2][pos1+c2-c1]==c2
	&& c[c1][c2][pos2]==r1 && c[c1][c2].size()-pos2-r2+r1-1>=0 && c[c1][c2][pos2+r2-r1]==r2){
		if(!bio[hashiraj(r1, r2, c1, c2)]){
//			printf("cudo\n");
			bio[hashiraj(r1, r2, c1, c2)]=1;
			return 1;
		}
	}
	return 0;
}

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++){
			l[i][j]=a[i][j];
		}
	}
	for(int i=0; i<n; i++){
		upd1(i, 1);
	}
	for(int i=0; i<m; i++){
		upd2(i, 0);
	}
	int br=0;
	for(int i=1; i<n-1; i++){
		for(int j=1; j<m-1; j++){
			if(provjeri(i, j)){
				br++;
			}
		}
	}
	return br;
}

/*
int main(){
	scanf("%d%d", &n, &m);
	for(int i=0; i<n; i++){
		for(int j=0; j<m; j++){
			scanf("%d", &l[i][j]);
		}
	}
	for(int i=0; i<n; i++){
		upd1(i, 1);
	}
	for(int i=0; i<m; i++){
		upd2(i, 0);
	}
	int br=0;
	for(int i=1; i<n-1; i++){
		for(int j=1; j<m-1; j++){
			if(provjeri(i, j)){
				br++;
			}
		}
	}
	printf("%d\n", br);
	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...