Cod sursa(job #309040)

Utilizator Mishu91Andrei Misarca Mishu91 Data 29 aprilie 2009 14:23:12
Problema Matrice 2 Scor Ascuns
Compilator cpp Status done
Runda Marime 4.14 kb
# include <cstdio>
# include <vector>
# include <algorithm>
# include <time.h>

using namespace std;

# define FIN "matrice2.in"
# define FOUT "matrice2.out"
# define min(a, b) (a < b ? a : b)
# define pb push_back
# define MAXN 90005
# define MAXM 20005
# define MAXL 20

int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};

int N, M, i, j, CT, Parinte, q, w, r, l, x, y;;
int RMQ[MAXL][MAXN];
vector <int> Arb[MAXN];
int A[MAXN], Ind[MAXN], H[MAXN], T[MAXN], S[MAXN];

     int Cmp(int a, int b)
     {
         return A[a] > A[b];
     }
     
     int Codif(int X, int Y)
     {
         return (X - 1) * N + Y;
     }
     
     void Decodif(int &X, int &Y, int Nod)
     {
         (Nod % N) > 0 ? Y = Nod % N : Y = N;
         (Nod % N) > 0 ? X = Nod / N + 1 : X = Nod / N;
     }
     
     int Father(int Nod)
     {
         if (T[Nod] == Nod) return Nod;
         
         return T[Nod] = Father(T[Nod]);
     }
     
     void df(int Nod)
     {
         vector <int> :: iterator it;
     
         for (it = Arb[Nod].begin(); it != Arb[Nod].end(); ++it)
            if (!Ind[*it])
            {
                Ind[*it] = Ind[Nod] + 1;
                df(*it);
            }
     }
     
     void Solve()
     {
         int i, j, Xi, Yi, Xf, Yf, Nod, F;
         
         for (i = 1; i <= CT; ++i)
         {
             S[Ind[i]] = 1;
             
             Decodif(Xi, Yi, Ind[i]);
             
             for (j = 0; j < 4; ++j)
             {
                 Xf = Xi + dx[j]; Yf = Yi + dy[j];
                 
                 if (1 <= Xf && Xf <= N && 1 <= Yf && Yf <= N)
                 {
                     Nod = Codif(Xf, Yf);
                     
                     if (S[Nod])
                     {
                         F = Father(Nod);
                         
                         T[F] = Ind[i]; RMQ[0][F] = Ind[i];
                         
                         Arb[F].pb(Ind[i]); Arb[Ind[i]].pb(F);
                     }
                 }
             }
         }
     }
     
     void swap(int &A, int &B)
     {
         int aux;
         
         aux = A; A = B; B = aux;
     }

     int main()
     {
         double ll = clock();
         
         freopen(FIN, "r", stdin);
         freopen(FOUT, "w", stdout);
         
         scanf("%d%d", &N, &M);
         
         for (i = 1, CT = 0; i <= N; ++i)
            for (j = 1; j <= N; ++j)
            {
                scanf("%d", &A[++CT]);
                
                Ind[CT] = T[CT] = RMQ[0][CT] = CT;
            }
            
         sort(Ind + 1, Ind + CT + 1, Cmp);
         
         Solve();
         
         for (i = 1; i <= CT; ++i)
            if (RMQ[0][i] == i) Parinte = i;
            
         memset(Ind, 0, sizeof(Ind)); Ind[Parinte] = 1; df(Parinte);
         
         H[0] = H[1] = 0;
         for (i = 2; i <= CT; ++i) H[i] = H[i >> 1] + 1;
         
         RMQ[0][Parinte] = 0;
         for (i = 1; i <= H[CT]; ++i)
            for (j = 1; j <= CT; ++j)
               RMQ[i][j] = RMQ[i - 1][RMQ[i - 1][j]];
         
         for (i = 1; i <= M; ++i)
         {
             scanf("%d%d", &x, &y); q = (x - 1) * N + y;
             scanf("%d%d", &x, &y); w = (x - 1) * N + y;
             
             if (Ind[q] > Ind[w]) swap(q, w);
             
             while (Ind[q] < Ind[w]) w = RMQ[H[Ind[w] - Ind[q]]][w];
             
             if (q != w)
             {
                 l = H[Ind[q] - 1];
                 
                 while (l >= 0)
                 {
                     if (RMQ[l][q] != RMQ[l][w])
                     {
                         q = RMQ[l][q];
                         w = RMQ[l][w];
                     } else r = RMQ[l][q];
                     
                     --l;
                 }
                 
             } else r = q;
             
             printf("%d\n", A[r]);
         }
         
         //for (i = 1; i <= CT; ++i) printf("%d %d\n", RMQ[0][i], Ind[i]);
         //printf("%lf", (clock() - ll) / CLOCKS_PER_SEC);

         return 0;
     }