Pagini recente » Cod sursa (job #1201875) | prosoft-2016/clasament/10 | Cod sursa (job #490058) | Cod sursa (job #2502740) | Cod sursa (job #869635)
Cod sursa(job #869635)
#include <fstream>
#include <algorithm>
#include <set>
using namespace std;
ifstream F("matrice2.in");
ofstream G("matrice2.out");
const int Nmax = 305;
const int Qmax = 20010;
int N,M;
#define f first
#define s second
typedef struct
{
int x;
int y;
int ord;
} q_type;
struct q_comp
{
bool operator()(const q_type& a,const q_type& b)
{
return a.x < b.x || ( a.x == b.x && a.y < b.y );
}
};
typedef struct
{
int val;
int key;
} v_type;
struct v_comp
{
bool operator()(const v_type& a,const v_type& b)
{
return a.val > b.val;
}
};
q_type Q[Qmax];
v_type A[Nmax*Nmax];
set<int> Set[Nmax*Nmax];
// setul pointeaza la ordinea din query-urile sortate
int Mul[Nmax*Nmax];
int High[Nmax*Nmax];
int Ind[Nmax*Nmax];
// Ind pointeaza la Mul , Mul e varful multimii disjuncte
int Sol[Qmax],Val;
int Leg[Nmax*Nmax][4];
inline int make_nod( int i,int j )
{
return (i-1) * N + j;
}
inline pair<int,int> get_nod(int val)
{
int X = (val-1) / N;
int Y = val - X * N;
return make_pair( X , Y );
}
void Make_sets()
{
for (int i=1;i<=2*M;++i)
{
F>> Q[i].x >> Q[i].y ;
Q[i].ord = (i+1)/2;
Ind[ make_nod( Q[i].x , Q[i].y ) ] = make_nod( Q[i].x , Q[i].y );
Sol[ Q[i].ord ] |= Set[ Ind[ make_nod( Q[i].x , Q[i].y ) ] ].insert( Q[i].ord ).second;
}
}
bool Mark[Nmax*Nmax];
typedef set<int>::iterator ST;
void UniteSets(int N1,int N2) // unesc primul cu al 2-lea
{
for (ST it=Set[N1].begin();it!=Set[N1].end();++it)
{
ST jt = Set[N2].find( *it );
if ( jt != Set[N2].end() )
{
Sol[ *jt ] = Val;
Set[N2].erase( *jt );
}
else
Set[N2].insert( *it );
}
set<int>().swap( Set[N1] );
}
void Unite(int N1,int N2)
{
if ( N1 == N2 )
return;
//if ( Ind[N1] != Ind[N2] )
{
if ( Set[ Ind[N1] ].size() < Set[ Ind[N2] ].size() )
UniteSets(Ind[N1],Ind[N2]), Ind[N1] = Ind[N2];
else
UniteSets(Ind[N2],Ind[N1]), Ind[N2] = Ind[N1];
}
if ( High[N1] == High[N2] )
{
Mul[ N1 ] = Mul[ N2 ];
High[N2] ++;
}
else
{
if ( High[ N1 ] < High[ N2 ] )
Mul[ N1 ] = Mul[ N2 ];
else
Mul[ N2 ] = Mul[ N1 ];
}
}
inline int Go( int Nod )
{
if ( Mul[ Nod ] == Nod ) return Nod;
int Dad = Go( Mul[Nod] );
Mul[Nod] = Dad;
return Dad;
}
int main()
{
F>>N>>M;
for (int i=1;i<=N;++i)
for (int j=1;j<=N;++j)
{
int nod = make_nod(i,j);
F>>A[nod].val;
A[nod].key = nod;
Mul[nod] = nod;
High[nod] = 1;
if ( i > 1 ) Leg[nod][0] = make_nod(i-1,j);
if ( j > 1 ) Leg[nod][1] = make_nod(i,j-1);
if ( i < N ) Leg[nod][2] = make_nod(i+1,j);
if ( j < N ) Leg[nod][3] = make_nod(i,j+1);
}
Make_sets();
sort(A+1,A+N*N+1,v_comp());
for ( int i=1;i<=N*N;++i)
{
Val = A[i].val;
Mark[ A[i].key ] = 1;
for (int j=0;j<4;++j)
{
int to = Leg[A[i].key][j];
if ( Mark [ to ] == 1 && to != 0 )
Unite( Go( A[i].key ) , Go( to ) );
}
}
for (int i=1;i<=M;++i)
G<<Sol[i]<<'\n';
}