Nu aveti permisiuni pentru a descarca fisierul grader_test6.in
Cod sursa(job #2103084)
Utilizator | Data | 9 ianuarie 2018 19:25:55 | |
---|---|---|---|
Problema | Matrice 2 | Scor | 100 |
Compilator | cpp | Status | done |
Runda | Arhiva de probleme | Marime | 2.36 kb |
#include <bits/stdc++.h>
using namespace std;
ifstream fi( "matrice2.in" );
ofstream fo( "matrice2.out");
const int maxq = 2e4;
const int maxn = 300;
const int dx[4] = { -1, 0, 1, 0 };
const int dy[4] = { 0, 1, 0, -1 };
int n, k, Q, ans[maxq + 5], mt[maxn + 5][maxn + 5], t[maxn*maxn + 5];
struct cell {
int x, y, val;
bool operator < (const cell &aux) const {
return val > aux.val;
}
} v[maxn * maxn + 5];
struct query {
int x1, y1, x2, y2, idx;
bool operator < (const query &aux) const {
return ans[ idx ] > ans[ aux.idx ];
}
} q[maxq + 5];
int index( int row, int col ) {
return n * (row-1) + col;
}
int father( int x ) {
if (x == t[ x ])
return x;
return t[ x ] = father( t[ x ] );
}
void join( int x, int y ) {
int rx = father( x ), ry = father( y );
t[ rx ] = ry;
}
void connect( int r, int c, int lower ) {
int newx, newy;
for (int i = 0; i < 4; i++) {
newx = r + dx[ i ];
newy = c + dy[ i ];
if (newx > 0 && newx <= n && newy > 0 && newy <= n && mt[ newx ][ newy ] >= lower)
join( index( newx, newy ), index( r, c ) );
}
}
void update( int value ) {
for (int i = 1; i <= k; i++)
t[ i ] = i;
int p = 1;
sort( q + 1, q + Q + 1 );
for (int i = 1; i <= Q; i++) {
while (p <= k && v[ p ].val >= ans[ q[ i ].idx ] + value) {
connect( v[ p ].x, v[ p ].y, ans[ q[ i ].idx ] + value );
p++;
}
if (father( index( q[ i ].x1, q[ i ].y1 ) ) == father( index( q[ i ].x2, q[ i ].y2 ) ) )
ans[ q[ i ].idx ] += value;
}
}
int main()
{
int mx = 0;
fi >> n >> Q;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
fi >> mt[ i ][ j ];
v[ ++k ] = { i, j, mt[ i ][ j ] };
mx = max( mx, mt[ i ][ j ] );
}
}
sort( v + 1, v + k + 1 );
for (int i = 1; i <= Q; i++) {
fi >> q[ i ].x1 >> q[ i ].y1 >> q[ i ].x2 >> q[ i ].y2;
q[ i ].idx = i;
}
int lim = 1;
while ((lim << 1) <= mx)
lim <<= 1;
for (int step = lim; step >= 1; step >>= 1)
update( step );
for (int i = 1; i <= Q; i++)
fo << ans[ i ] << '\n';
fi.close();
fo.close();
return 0;
}