Cod sursa(job #2055261)

Utilizator mlc_oficialBoris Barca mlc_oficial Data 2 noiembrie 2017 23:35:49
Problema A+B Scor 0
Compilator cpp Status done
Runda teme_upb Marime 4.95 kb
#include "bits/stdc++.h"
using namespace std;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
static const int INF = 0x3f3f3f3f; static const long long INFL = 0x3f3f3f3f3f3f3f3fLL;
typedef vector<int> vi; typedef pair<int, int> pii; typedef vector<pair<int, int> > vpii; typedef long long ll;
template<typename T, typename U> static void amin(T &x, U y) { if(y < x) x = y; }
template<typename T, typename U> static void amax(T &x, U y) { if(x < y) x = y; }

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

class FastInput {
	bool _end;
public:
	FastInput() : _end(false) {}

	operator void*() { return _end ? 0 : (void*)this; }

	template<typename T>
	void read_signed(T *res) {
		char c = skip();
		bool sign = false;
		if(c == '-') sign = true, c = gc();
		T x = 0;
		for(; '0' <= c && c <= '9'; c = gc())
			x = x * 10 + (c - '0');
		*res = !sign ? x : -x;
	}

	FastInput &operator()(int &res) { read_signed(&res); return *this; }

private:
	static char gc() {
#if defined(__GNUC__) && !defined(__MINGW32__)
		return (char)getchar_unlocked();
#elif defined(_MSC_VER)
		return (char)_getchar_nolock();
#else
		return (char)getchar();
#endif
	}

	static bool is_delim(char c) {
		return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == EOF;
	}

	char skip() {
		if(_end) return EOF;
		char c;
		for(c = gc(); c != -1 && is_delim(c); c = gc());
		if(c == EOF) _end = true;
		return c;
	}
} in;

class FastOutput {
public:
	template<typename T>
	void print_signed(T x) {
		char buf[24]; int n = 0; bool sign = false;
		if(x < 0) sign = true;
		//depends on the -x % y behaviour
		do buf[n ++] = x % 10, x /= 10; while(x != 0);
		if(!sign) {
			while(n > 0) pc('0' + buf[-- n]);
		} else {
			pc('-');
			while(n > 0) pc('0' - buf[-- n]);
		}
	}

	void print_char(char x) {
		pc(x);
	}

	FastOutput &operator()(char x) { print_char(x); return *this; }
	FastOutput &operator()(int x) { print_signed(x); return *this; }

private:
	static void pc(char c) {
#if defined(__GNUC__) && !defined(__MINGW32__)
		putchar_unlocked(c);
#elif defined(_MSC_VER)
		_putchar_nolock(c);
#else
		putchar(c);
#endif
	}
} out;

class SparseTable2D {
public:
	enum { N = (1000 + 7) / 8 * 8, LogN = 10 };
	typedef short Val;
	alignas(16) Val table[LogN + 1][LogN + 1][N + 8][N + 8];

	template<typename Array>
	void init(int n, int m, const Array &a) {
		int lgn = log2i(n), lgm = log2i(m);
		rep(y, n) rep(x, m)
			table[0][0][y][x] = a[y][x];
		for(int j = 1; j <= lgm; ++ j) {
			int w = m - (1 << j) + 1;
			rep(y, n)
				max_vector(table[0][j][y], table[0][j - 1][y], table[0][j - 1][y] + (1 << (j - 1)), w);
		}
		for(int i = 1; i <= lgn; ++ i) for(int j = 0; j <= lgm; ++ j) {
			int h = n - (1 << i) + 1, w = m - (1 << j) + 1;
			rep(y, h)
				max_vector(table[i][j][y], table[i - 1][j][y], table[i - 1][j][y + (1 << (i - 1))], w);
		}
	}

	//[yL,yR] x [xL,xR]
	Val query(int yL, int xL, int yR, int xR) const {
		int lgy = log2i(yR - yL + 1);
		int lgx = log2i(xR - xL + 1);
		const auto &v = table[lgy][lgx];
		yR -= (1 << lgy) - 1;
		xR -= (1 << lgx) - 1;
		return mymax(mymax(v[yL][xL], v[yL][xR]), mymax(v[yR][xL], v[yR][xR]));
	}

private:
	static void max_vector(Val *dst, const Val *src1, const Val *src2, int n) {
		if(((intptr_t)src2 & 15) == 0) {
			for(int i = 0; i < n; i += 8) {
				auto x = _mm_load_si128((const __m128i*)(src1 + i));
				auto y = _mm_load_si128((const __m128i*)(src2 + i));
				auto z = _mm_max_epi16(x, y);
				_mm_store_si128((__m128i*)(dst + i), z);
			}
		} else {
			for(int i = 0; i < n; i += 8) {
				auto x = _mm_load_si128((const __m128i*)(src1 + i));
				auto y = _mm_loadu_si128((const __m128i*)(src2 + i));
				auto z = _mm_max_epi16(x, y);
				_mm_store_si128((__m128i*)(dst + i), z);
			}
		}
	}

	static Val mymax(Val x, Val y) {
		return x < y ? y : x;
	}

	static int log2i(uint32_t n) {
		return bsr(n);
	}

	static int bsr(uint32_t x) {
#if defined(__GNUC__)
		return 31 - __builtin_clz(x);
#else
		int r = 0;
		if(x & 0xffff0000U) x >>= 16, r += 16;
		if(x & 0xff00U) x >>= 8, r += 8;
		if(x & 0xf0U) x >>= 4, r += 4;
		if(x & 0xcU) x >>= 2, r += 2;
		if(x & 0x2U) r += 1;
		return r;
#endif
	}
};

int main() {
	int n; int m;
	while(in(n)(m)) {
		vector<vector<int> > a(n, vector<int>(m));
		for(int i = 0; i < n; ++ i) for(int j = 0; j < m; ++ j)
			in(a[i][j]);
		vector<vector<short>> dp(n + 1, vector<short>(m + 1));
		for(int i = n - 1; i >= 0; -- i)
			for(int j = m - 1; j >= 0; -- j)
				dp[i][j] = a[i][j] == 0 ? 0 : min({ dp[i + 1][j], dp[i][j + 1], dp[i + 1][j + 1] }) + 1;
		static SparseTable2D st2d;
		st2d.init(n, m, dp);
		int q;
		in(q);
		rep(ii, q) {
			int yL, xL, yR, xR;
			in(yL)(xL)(yR)(xR), -- yL, -- xL;
			int lo = 0, up = min(yR - yL, xR - xL);
			while(up - lo > 0) {
				int mid = (lo + up + 1) / 2;
				int val = st2d.query(yL, xL, yR - mid, xR - mid);
				if(val >= mid)
					lo = mid;
				else
					up = mid - 1;
			}
			out(lo)('\n');
		}
	}
	return 0;
}