Submission #421207

#TimeUsernameProblemLanguageResultExecution timeMemory
421207MohamedAhmed04Rectangles (IOI19_rect)C++14
59 / 100
2357 ms1048580 KiB
#include <bits/stdc++.h>
#include "rect.h"
//#include "grader.cpp"

using namespace std ;

const int MAX = 2501 ;

struct BIT
{
	vector<int>bit , v ;
	int n ;

	int getidx(int x)
	{
		int idx = upper_bound(v.begin() , v.end() , x) - v.begin() ;
		return idx ;
	}

	void Add(int i , int x)
	{
		for(; i <= n ; i += (i & (-i)))
			bit[i] += x ;
	}

	void Insert(int i)
	{
		Add(getidx(i) , 1) ;
	}

	void Erase(int i)
	{
		Add(getidx(i) , -1) ;
	}

	int get(int i)
	{
		int sum = 0 ;
		for(; i > 0 ; i -= (i & (-i)))
			sum += bit[i] ;
		return sum ;
	}

	int query(int i)
	{
		return get(getidx(i)) ;
	}

	void init(vector<int>&v2)
	{
		n = v2.size() ;
		v = v2 ;
		sort(v.begin() , v.end()) ;
		bit = vector<int>(n+1 , 0) ;
		for(auto &i : v)
			Insert(i) ;
	}
};

BIT tree[MAX][MAX] ;
vector<int>candi[MAX] ;
stack<int>st[MAX] ;
vector<int>v2[MAX][MAX] ;
vector<bool>mark[MAX] ;

int n , m ;

int calc(int i , int j , int i2 , int last)
{
	int j2 = j-1 ;
	i2++ ;
	if(j2 < 0 || i2 >= i)
		return 0ll ;
	return (tree[i2][j2].query(last+1) - tree[i2][j2].query(j)) ;
}

vector< vector<int> >a ;
vector<int>erased ;
stack<int>st2 ;

void AddRow(int i)
{
	while(st2.size())
		st2.pop() ;
	for(int j = m-1 ; j >= 0 ; --j)
	{
		while(st2.size() && a[i][j] > a[i][st2.top()])
			v2[i][j].push_back(st2.top()) , st2.pop() ;
		if(st2.size())
			v2[i][j].push_back(st2.top()) ;
		while(st2.size() && a[i][st2.top()] == a[i][j])
			st2.pop() ;
		st2.push(j) ;
		sort(v2[i][j].begin() , v2[i][j].end()) ;
		tree[i][j].init(v2[i][j]) ;
	}
	if(!i)
		return ;
	for(int j = 0 ; j < m ; ++j)
	{
		erased.clear() ;
		for(auto &k : v2[i-1][j])
		{
			if(!binary_search(v2[i][j].begin() , v2[i][j].end() , k))
				erased.push_back(k) ;
		}
		for(auto &k : erased)
		{
			for(int i2 = i-1 ; i2 >= 0 ; --i2)
			{
				if(!binary_search(v2[i2][j].begin() , v2[i2][j].end() , k))
					break ;
				tree[i2][j].Erase(k) ;
			}
		}
	}
}

long long count_rectangles(std::vector<std::vector<int> > v) 
{
	a = v ;
	n = a.size() , m = a[0].size() ;
	long long ans = 0 ;
	for(int i = 0 ; i < n ; ++i)
	{
		for(int j = 0 ; j < m ; ++j)
		{
			while(st[j].size() && a[i][j] > a[st[j].top()][j])
				candi[j].push_back(st[j].top()) , st[j].pop() ;
			if(st[j].size())
				candi[j].push_back(st[j].top()) ;
			while(st[j].size() && a[st[j].top()][j] == a[i][j])
				st[j].pop() ;
			st[j].push(i) ;
			sort(candi[j].begin() , candi[j].end()) ;
			mark[j] = vector<bool>(candi[j].size() , 0) ;
		}
		for(int j = 0 ; j < m ; ++j)
		{
			for(auto &i2 : candi[j])
			{
				int idx = lower_bound(candi[j].begin() , candi[j].end() , i2) - candi[j].begin() ;
				if(mark[j][idx])
					continue ;
				int last = j ;
				for(int k = j ; k < m ; ++k)
				{
					if(!binary_search(candi[k].begin() , candi[k].end() , i2))
						break ;
					last = k ;
				}
				for(int k = j ; k <= last ; ++k)
				{
					ans += calc(i , k , i2 , last) ;
					if(k != j)
					{
						idx = lower_bound(candi[k].begin() , candi[k].end() , i2) - candi[k].begin() ;
						mark[k][idx] = 1 ;
					}
				}
			}
			candi[j].clear() , mark[j].clear() ;
		}
		AddRow(i) ;
	}
	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...