Submission #1241827

#TimeUsernameProblemLanguageResultExecution timeMemory
1241827Zbyszek99Rectangles (IOI19_rect)C++20
72 / 100
2567 ms1114112 KiB
#include "rect.h"
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define vi vector<int>
#define vl vector<long long>
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace std;
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;

const int tree_siz = 1024*8-1;
int sum[tree_siz+1];

int get_sum(int akt, int p1, int p2, int s1, int s2)
{
	if(p2 < s1 || p1 > s2) return 0;
	if(p1 >= s1 && p2 <= s2) return sum[akt];
	return get_sum(akt*2,p1,(p1+p2)/2,s1,s2)+get_sum(akt*2+1,(p1+p2)/2+1,p2,s1,s2);
}

void upd(int v)
{
	sum[v] = sum[v*2]+sum[v*2+1];
	if(v != 1) upd(v/2);
}

void change(int ind, int x)
{
	sum[tree_siz/2+ind+1] += x;
	upd((tree_siz/2+1+ind)/2);
}

int cp(pii x)
{
	return x.ff * 2600 + x.ss;
}

pii de(int x)
{
	return {x/2600,x%2600};
}

map<int,short> X[2501];
map<int,short> Y[2501];
vi X_segs[2501][2501];
vi Y_segs[2501][2501];

vi count_regions(vi& x)
{
	vi ans;
	stack<int> st;
	rep(i,siz(x))
	{
		while(!st.empty() && x[st.top()] < x[i]) st.pop();
		if(i != 0 && siz(st) != 0)
		{
			int end_ = st.top()+1;
			if(end_ <= i-1)
			{
				ans.pb(cp({end_,i-1}));
			}
		}
		st.push(i);
	}
	while(!st.empty()) st.pop();
	for(int i = siz(x)-1; i >= 0; i--)
	{
		while(!st.empty() && x[st.top()] < x[i]) st.pop();
		if(i != siz(x)-1 && siz(st) != 0)
		{
			int end_ = st.top()-1;
			if(end_ >= i+1)
			{
				ans.pb(cp({i+1,end_}));
			}
		}
		st.push(i);
	}
	sort(all(ans));
	vi ans2;
	int pop = -1;
	forall(it2,ans)
	{
		if(it2 == pop) continue;
		ans2.pb(it2);
		pop = it2;
	}
	return ans2;
}

ll count_rectangles(vector<vi> arr) 
{
	int n = siz(arr);
	int m = siz(arr[0]);
	vi segs;
	rep2(i,1,n-2)
	{
		segs = count_regions(arr[i]);
		forall(it,segs)
		{
			Y[i][it] = i;
		}
	}
	for(int i = n-2; i >= 0; i--)
	{
		pii it;
		forall(it2,Y[i])
		{
			it = de(it2.ff);
			if(Y[i+1].find(it2.ff) != Y[i+1].end()) Y[i][it2.ff] = Y[i+1][it2.ff];
			Y_segs[i][it.ff].pb(cp({Y[i][it2.ff],it.ss}));
		}
	}
	vi arr2(n);
	rep2(j,1,m-2)
	{
		rep(i,n) arr2[i] = arr[i][j];
		segs = count_regions(arr2);
		forall(it,segs)
		{
			X[j][it] = j;
		}
	}
	for(int j = m-2; j >= 0; j--)
	{
		pii it;
		forall(it2,X[j])
		{
			it = de(it2.ff);
			if(X[j+1].find(it2.ff) != X[j+1].end()) X[j][it2.ff] = X[j+1][it2.ff];
			X_segs[it.ff][j].pb(cp({it.ss,X[j][it2.ff]}));
		}
	}
	ll ans = 0;
	rep2(i,1,n-2)
	{
		rep2(j,1,m-2)
		{
			sort(all(X_segs[i][j]));
			sort(all(Y_segs[i][j]));
			reverse(all(Y_segs[i][j]));
			int cur_Y = siz(Y_segs[i][j])-1;
			forall(it,Y_segs[i][j])
			{
				change(it % 2600,1);
			}
			forall(it,X_segs[i][j])
			{
				while(cur_Y >= 0 && Y_segs[i][j][cur_Y]/2600 < it/2600)
				{
					change(Y_segs[i][j][cur_Y]%2600,-1);
					cur_Y--;
				}
				ans += get_sum(1,0,tree_siz/2,0,it%2600);
			}
			rep(k,cur_Y+1)
			{
				change(Y_segs[i][j][k]%2600,-1);
			}
		}
	}
	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...