Cod sursa(job #467312)

Utilizator FlorianFlorian Marcu Florian Data 28 iunie 2010 14:05:13
Problema Cadrane Scor 80
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 3.12 kb
using namespace std;
#include<fstream>
#include<algorithm>
const int MAX_N = 100007, oo = 0x3f3f3f3f;
struct punct { int x,y; };
punct A[MAX_N], B[MAX_N];
punct D[MAX_N], C[MAX_N]; 
int c,d;
int N, H[3 * MAX_N + 2], full[3 * MAX_N + 2];
struct crescator_dupa_x
{
	bool operator()(const punct &a, const punct &b)const
	{
		return a.x < b.x;
	}
};
struct crescator_dupa_y
{
	bool operator()(const punct &a, const punct &b)const
	{
		if(a.y == b.y) return a.x > b.x;
		return a.y < b.y;
	}
};
inline int min( int a, int b) { return a<b?a:b; }
inline int max( int a, int b) { return a>b?a:b; }
inline void update(int n, int l, int r, int st, int dr, int v)
{
	if( st <= l && r <= dr )
	{
		full[n] += v;
		H[n] += v;
		return;
	}
	int m = (l+r)>>1;
	if( st <= m ) update( 2*n, l, m, st, dr, v);
	if( dr > m ) update( 2*n+1, m+1, r, st, dr, v);
	H[n] = min( H[2*n], H[2*n+1] ) + full[n];
}
int upper(int Y)
{
	int st = 1, dr = N, m;
	while( st <= dr)
	{
		m = (st + dr)>>1;
		if( B[m].y == Y && ( m == N || B[m+1].y != Y )) return m;
		else if( B[m].y <= Y ) st = m + 1;
		else dr = m - 1;
	}
	return 0;
}
int upper2(int Y)
{
	int st = 1, dr = c, m;
	if( C[1].y > Y ) return 0;
	if( C[c].y <= Y ) return c;
	while( st <= dr)
	{
		m = (st + dr)>>1;
		if( C[m].y <= Y && C[m+1].y > Y ) return m;
		else if( C[m].y > Y ) dr = m - 1;
		else st = m + 1;
	}
	return 0;
}
int lower(int Y)
{
	int  st = 1, dr = N, m;
	while( st <= dr)
	{
		m = (st + dr)>>1;
		if( B[m].y == Y && ( m == 1 || B[m-1].y != Y )) return m;
		else if( B[m].y < Y ) st = m + 1;
		else dr = m - 1;
	}
	return 0;
}
int lower2(int Y)
{
	int  st = 1, dr = d, m;
	if( D[d].y  < Y ) return d + 1;
	if( D[1].y >= Y ) return 1;
	while( st <= dr)
	{
		m = (st + dr)>>1;
		if( D[m - 1].y < Y && D[m].y >= Y ) return m;
		else if( D[m].y < Y ) st = m + 1;
		else dr = m - 1;
	}
	return 0;
}
int sol;
void check(int X)
{
	int i, low, up, pe = 0, tmp = oo;
	for(i = 1; i <= N; ++i)
		if( B[i].x < X ) C[++c] = B[i]; 
		else if( B[i].x > X ) D[++d] = B[i];
		else ++pe;
	for(i = 1; i <= N; ++i)
	{
		low = lower2( B[i].y ); low = d - low + 1; 
		up = upper2( B[i].y );
		if( low + up + pe < tmp ) tmp = low + up + pe;
	}
	sol = tmp;
}
int main()
{
	ifstream in("cadrane.in"); ofstream out("cadrane.out");
	in>>N;
	int i, j, X;
	for(i = 1; i <= N; ++i)
	{
		in>>A[i].x>>A[i].y;
		B[i] = A[i];
	}
	sort( A + 1, A+N+1, crescator_dupa_x());
	sort( B + 1, B+N+1, crescator_dupa_y());
	int cnt = N, tmp = 1;
	for(i = 1; i <= N; ++i)
	{
		update( 1, 1, N, i, i, cnt);
		if( i < N && B[i].y == B[i+1].y ) ++tmp;
		else
		{
			cnt -= tmp;
			tmp = 1;
		}
		if( B[i].x == A[1].x ) ++cnt;
	}
	sol = H[1]; int l, u; X = A[1].x;
	i = 1;
	while( i <= N && A[1].x == A[i].x ) ++i;
	for(; i <= N; ++i)
	{
		if( A[i].x != A[i-1].x )
		{
			for(j = i - 1; j && A[j].x == A[i-1].x ; --j)
			{
				l = lower( A[j].y );
				u = upper( A[j].y );
				update( 1, 1, N, 1, u, -1);
				update( 1, 1, N, l, N, 1);
			}
			if( H[1] > sol ) { sol = H[1]; X = A[i].x; }
			
		}
	}
	check(X);
	out<<sol<<"\n";
	return 0;
}