模板
Tab = 3
读入优化
char gc() {
static char buf[1 << 17], *S, *T;
if(S == T) T = (S = buf) + fread(buf, 1, 1 << 17, stdin);
return S == T ? EOF : *S ++;
}
template<class T> void read(T &x) {
x = 0; char c = gc(); bool na = 0;
for(; c < '0' || c > '9'; c = gc()) na |= c == '-';
for(; c >= '0' && c <= '9'; c = gc()) x = x * 10 + (c & 15);
if(na) x = -x;
}
组合数模板
int C(int n, int m) {
return n < m ? 0 : 1ll * fac[n] * fav[m] % mod * fav[n - m] % mod;
}
void binom(int n) {
fac[0] = 1;
for(int i = 1; i <= n; i ++) fac[i] = 1ll * fac[i - 1] * i % mod;
fav[n] = qpow(fac[n], mod - 2);
for(int i = n; i >= 1; i --) fav[i - 1] = 1ll * fav[i] * i % mod;
}
dinic
namespace net {
const int N = 510, M = 4e5 + 10;
struct Edge {
int v, c, f, nxt;
} e[M];
int ec, hd[N], n;
void init(int _n) {
n = _n; fill(hd + 1, hd + n + 1, -1); ec = 0;
}
void add(int u, int v, int c) {
e[ec] = (Edge) {v, c, 0, hd[u]}; hd[u] = ec ++;
e[ec] = (Edge) {u, 0, 0, hd[v]}; hd[v] = ec ++;
}
int dis[N], cur[N];
bool bfs() {
fill(dis + 1, dis + n + 1, -1);
queue<int> q; q.push(1); dis[1] = 0;
while(q.size()) {
int u = q.front(); q.pop();
for(int i = hd[u]; ~ i; i = e[i].nxt) {
int v = e[i].v;
if(e[i].f < e[i].c && -1 == dis[v]) {
dis[v] = dis[u] + 1; q.push(v);
}
}
}
return ~ dis[n];
}
int dfs(int u, int a) {
if(u == n || a == 0) return a;
int ans = 0, f;
for(int &i = cur[u]; ~ i; i = e[i].nxt) {
int v = e[i].v;
if(dis[v] == dis[u] + 1 && (f = dfs(v, min(a, e[i].c - e[i].f))) > 0) {
ans += f; e[i].f += f; e[i ^ 1].f -= f;
if((a -= f) == 0) break ;
}
}
return ans;
}
int dinic() {
int ans = 0;
while(bfs()) {
copy(hd + 1, hd + n + 1, cur + 1);
ans += dfs(1, INF);
}
return ans;
}
}
倍增lca
f[u][0] = fa; d[u] = d[fa] + 1;
for(int i = 1; i < lgn; i ++)
f[u][i] = f[f[u][i - 1]][i - 1];
int lca(int u, int v) {
if(d[u] < d[v]) swap(u, v);
int c = d[u] - d[v];
for(int i = lgn - 1; ~ i; i --)
if(c >> i & 1) u = f[u][i];
if(u == v) return u;
for(int i = lgn - 1; ~ i; i --)
if(f[u][i] ^ f[v][i]) {
u = f[u][i]; v = f[v][i];
}
return f[u][0];
}
for(lgn = 1; (1 << lgn) <= n; lgn ++) ;
建图 + 最短路
namespace G {
const int M = N;
struct Edge { int v, w; };
vector<Edge> G[M];
struct Node {
int u, d;
bool operator < (const Node &b) const {
return d > b.d;
}
};
int n;
void init(int _n) {
n = _n;
}
void link(int u, int v, int w) {
G[u].push_back((Edge) {v, w});
}
void Dijkstra(int s, int *d) {
fill(d + 1, d + n + 1, INF);
priority_queue<Node> pq; pq.push((Node) {s, d[s] = 0});
while(pq.size()) {
int u = pq.top().u, du = pq.top().d; pq.pop();
if(d[u] < du) continue ;
for(int i = 0; i < (int) G[u].size(); i ++) {
Edge &e = G[u][i];
if(d[e.v] > d[u] + e.w) {
d[e.v] = d[u] + e.w; pq.push((Node) {e.v, d[e.v]});
}
}
}
}
}
fft
const db pi = 2 * acos(-1);
struct comp {
db x, y;
comp() {}
comp(db a, db b) : x(a), y(b) {}
comp operator + (const comp &b) const { return comp(x + b.x, y + b.y); }
comp operator - (const comp &b) const { return comp(x - b.x, y - b.y); }
comp operator * (const comp &b) const { return comp(x * b.x - y * b.y, b.x * y + x * b.y); }
} W[N], A[N], B[N];
int len, rev[N];
void init(int n) {
int k = 0;
for(len = 1; len <= n; len <<= 1) k ++;
for(int i = 1; i < len; i ++)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (k - 1));
for(int i = 0; i < len; i ++)
W[i] = comp(cos(pi * i / len), sin(pi * i / len));
}
void fft(comp *a, int ty) {
for(int i = 1; i < len; i ++)
if(i < rev[i]) swap(a[i], a[rev[i]]);
static comp t1, t2;
for(int i = 1; i < len; i <<= 1) {
for(int j = 0; j < len; j += i << 1) {
for(int k = j; k < j + i; k ++) {
t1 = a[k], t2 = W[len / (i << 1) * (k - j)] * a[k + i];
a[k] = t1 + t2; a[k + i] = t1 - t2;
}
}
}
if(ty == -1) {
reverse(a + 1, a + len);
for(int i = 0; i < len; i ++)
a[i].x /= len, a[i].y /= len;
}
}
纯NTT
int rev[N], len, w[N], inv_w[N];
void InitNTT(int n) {
int k = 0;
for(len = 1; len <= n; len <<= 1) k ++;
for(int i = 1; i < len; i ++)
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (k - 1));
w[0] = inv_w[0] = 1;
int v = qpow(_g, (mod - 1) / len);
for(int i = 1; i < len; i ++)
inv_w[len - i] = w[i] = 1ll * w[i - 1] * v % mod;
}
void NTT(int *a, const int *w) {
for(int i = 1; i < len; i ++)
if(i < rev[i]) swap(a[i], a[rev[i]]);
for(int i = 1; i < len; i <<= 1) {
for(int j = 0, t = len / (i << 1); j < len; j += i << 1) {
const int *wn = w;
for(int k = j; k < j + i; k ++, wn += t) {
int t1 = a[k], t2 = 1ll * *wn * a[k + i] % mod;
a[k] = (t1 + t2) % mod; a[k + i] = (t1 - t2 + mod) % mod;
}
}
}
if(w == inv_w) {
int v = mod - (mod - 1) / len;
for(int i = 0; i < len; i ++)
a[i] = 1ll * a[i] * v % mod;
}
}
二维st表
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 1003;
int n, m, lg[N], a[N][N][10][10];
short b[N][N];
int query(int x1, int y1, int x2, int y2) {
int k1 = lg[x2 - x1 + 1], k2 = lg[y2 - y1 + 1];
return max(max(a[x1][y1][k1][k2], a[x2 - (1 << k1) + 1][y1][k1][k2]),
max(a[x1][y2 - (1 << k2) + 1][k1][k2], a[x2 - (1 << k1) + 1][y2 - (1 << k2) + 1][k1][k2]));
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= m; j ++) {
scanf("%hd", &b[i][j]);
if(b[i][j]) a[i][j][0][0] = min(a[i - 1][j][0][0], min(a[i][j - 1][0][0], a[i - 1][j - 1][0][0])) + 1;
}
}
for(int i = 2; i <= max(n, m); i ++) lg[i] = lg[i >> 1] + 1;
for(int i = 1; i <= lg[m]; i ++) {
for(int x = 1; x <= n; x ++) {
for(int y = 1; y + (1 << i) - 1 <= m; y ++) {
a[x][y][0][i] = max(a[x][y][0][i - 1], a[x][y + (1 << (i - 1))][0][i - 1]);
}
}
}
for(int i = 1; i <= lg[n]; i ++) {
for(int j = 0; j <= lg[m]; j ++) {
for(int x = 1; x + (1 << i) - 1 <= n; x ++) {
for(int y = 1; y + (1 << j) - 1 <= m; y ++) {
a[x][y][i][j] = max(a[x][y][i - 1][j], a[x + (1 << (i - 1))][y][i - 1][j]);
}
}
}
}
int t; scanf("%d", &t);
while(t --) {
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
int l = 1, r = min(x2 - x1 + 1, y2 - y1 + 1), ans = 0;
while(l <= r) {
int mid = (l + r) >> 1;
if(query(x1 + mid - 1, y1 + mid - 1, x2, y2) >= mid) l = (ans = mid) + 1;
else r = mid - 1;
}
printf("%d\n", ans);
}
return 0;
}