Submission #1212491

#TimeUsernameProblemLanguageResultExecution timeMemory
1212491loiiii12358Rectangles (IOI19_rect)C++20
37 / 100
5126 ms1016888 KiB
#include "rect.h"
#include <bits/stdc++.h>
using namespace std;

struct coor{
	int r,c;
	coor(){
		r=c=0;
	}
	coor(int x,int y){
		r=x;c=y;
	}
};
struct segment{
	int r,R,c,C;
	segment(){
		r=R=c=C=-1;
	}
	segment(int x,int X,int y,int Y){
		r=x;R=X;c=y;C=Y;
	}
};

vector<set<int>> rowset,colset;
vector<vector<coor>> countvec;
vector<pair<int,coor>> vec;
vector<vector<segment>> grid;

long long count_rectangles(vector<vector<int> > a) {
	int n=a.size(),m=a[0].size();
	long long ans=0;
	vec.resize(n*m);countvec.resize(7000009);rowset.resize(n);colset.resize(m);
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			vec[i*m+j]={a[i][j],coor(i,j)};
			countvec[a[i][j]].push_back(coor(i,j));
			rowset[i].insert(j);
			colset[j].insert(i);
		}
	}
	sort(vec.begin(),vec.end(),[](pair<int,coor> A,pair<int,coor> B){
		return A.first<B.first;
	});
	grid.resize(n,vector<segment>(m,segment()));
	for(int i=0;i<n*m;i++){
		int r=vec[i].second.r,c=vec[i].second.c;
		for(auto u:countvec[a[r][c]]){
			rowset[u.r].erase(u.c);
			colset[u.c].erase(u.r);
		}
		countvec[a[r][c]].clear();
		auto u=colset[c].lower_bound(r);
		if(u==colset[c].end()){
			grid[r][c].R=n-1;
		}else{
			grid[r][c].R=(*u)-1;
		}
		if(u==colset[c].begin()){
			grid[r][c].r=0;
		}else{
			grid[r][c].r=(*--u)+1;
		}
		u=rowset[r].lower_bound(c);
		if(u==rowset[r].end()){
			grid[r][c].C=m-1;
		}else{
			grid[r][c].C=(*u)-1;
		}
		if(u==rowset[r].begin()){
			grid[r][c].c=0;
		}else{
			grid[r][c].c=(*--u)+1;
		}
		bool can=(grid[r][c].r>0&&grid[r][c].R<n-1&&grid[r][c].c>0&&grid[r][c].C<m-1);
		for(int j=grid[r][c].r;j<=grid[r][c].R;j++){
			if(!can){
				break;
			}
			for(int k=grid[r][c].c;k<=grid[r][c].C;k++){
				if(grid[j][k].r==-1){
					can=false;
					break;
				}else if(grid[j][k].r<grid[r][c].r){
					can=false;
					break;
				}else if(grid[j][k].R>grid[r][c].R){
					can=false;
					break;
				}else if(grid[j][k].c<grid[r][c].c){
					can=false;
					break;
				}else if(grid[j][k].C>grid[r][c].C){
					can=false;
					break;
				}
			}
		}
		if(can){
			ans++;
		}
	}
	return ans;
}
#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...