Problem p00653 (C++) — buggy submission, verdict: Time Limit Exceeded

#include "algorithm"
#include "cmath"
#include "cstdio"
#include "cstring"
#include "ctime"
#include "iostream"
#include "map"
#include "memory.h"
#include "queue"
#include "set"
#include "stack"
#include "string"
#include "vector"
#define int_max 0x7fffffff
#define ll_max 0x7fffffffffffffffLL
#define fr first
#define se second
typedef long long ll;
typedef unsigned long long llu;
using namespace std;
int mp[2000003];
int rmq_r[2100][1100];
int rmq_c[2100][1100];
int N, M, n, m, q;
int tot, tp;
/*void rmq_r_init(int row,int l,int r)
{
        rmq_r[row][0][1]=rmq_r[row][0][0];
        for(int i=1;i<N;i++)
        rmq_r[row][i][1]=min(rmq_r[row][i][0],rmq_r[row][i-1][1]);
        rmq_r[row][N-1][2]=rmq_r[row][N-1][2];
        for(int i=N-2;i>=0;i--)
        rmq_r[row][i][2]=min(rmq_r[row][i][0],rmq_r[row][i+1][0]);
}
void rmq_c_init(int row,int l,int r)
{
        rmq_c[row][0][1]=rmq_c[row][0][0];
        for(int i=1;i<N;i++)
        rmq_c[row][i][1]=min(rmq_c[row][i][0],rmq_r[row][i-1][1]);
        for(int i=N-2;i>=0;i--)
        rmq_c[row][i][0]=min(rmq_c[row][i][0],rmq_r[row][i+1][0]);
}*/
int rmq_findr(int row, int l, int r) {
  int ans = int_max;
  for (int i = l; i <= r; i++)
    ans = min(ans, rmq_r[row][i]);
  return ans;
}
int rmq_findc(int row, int l, int r) {
  int ans = int_max;
  for (int i = l; i <= r; i++)
    ans = min(ans, rmq_c[row][i]);

  return ans;
}
int gaor(int x_1, int y_1, int x_2, int y_2) {

  int ans = int_max;
  if (x_1 > x_2 || y_1 > y_2)
    return ans;

  int sx_1 = x_1 / N, sx_2 = x_2 / N;
  int sy_1 = y_1 / M, sy_2 = y_2 / M;
  int x1 = x_1 % N, x2 = x_2 % N;
  //
  for (int k = sy_1 + 1; k < sy_2; k++) {
    ans = min(ans, rmq_findr(sx_1 * M + k, x1, x2));
  }
  // printf("%d\\n",ans);
  int yy = (sy_1 + 1) * M;

  for (int i = x_1; i <= x_2; i++)
    for (int j = y_1; j < yy; j++) {
      ans = min(ans, mp[i * tp + j]);
      /// printf("-->%d\\n",mp[i][j]);
    }
  yy = (sy_2)*M; // printf("%d\\n",yy);
  for (int i = x_1; i <= x_2; i++)
    for (int j = yy; j <= y_2; j++) {
      ans = min(ans, mp[i * tp + j]);
      // printf("-->%d\\n",mp[i][j]);
    }
  return ans;
}
int gaoc(int x_1, int y_1, int x_2, int y_2) {

  int ans = int_max;
  if (x_1 > x_2 || y_1 > y_2)
    return ans;
  int sx_1 = x_1 / N, sx_2 = x_2 / N;
  int sy_1 = y_1 / M, sy_2 = y_2 / M;
  int x1 = y_1 % M, x2 = y_2 % M;
  //	printf("%d %d %d %d %d %d %d %d\\n",x_1,y_1,x_2,y_2,x1,x2,N,M);
  for (int k = sx_1 + 1; k < sx_2; k++) {
    for (int i = 0; i < M; i++)
      //	printf("%d\\n",rmq_c[k*M+sy_1][i][0]);
      ans = min(ans, rmq_findc(k * M + sy_1, x1, x2));
  }
  //	printf("%d\\n",ans);
  int xx = (sx_1 + 1) * N;
  for (int j = y_1; j <= y_2; j++)
    for (int x = x_1; x < xx; x++) {
      ans = min(ans, mp[x * tp + j]);
      //	printf("-->%d\\n",mp[x][j]);
    }

  xx = sx_2 * N;

  for (int j = y_1; j <= y_2; j++)
    for (int x = xx; x <= x_2; x++) {
      ans = min(ans, mp[x * tp + j]);
      //		printf("-->%d\\n",mp[x][j]);
    }
  return ans;
}
int main() {
  //	freopen("1.in","r",stdin);
  //	freopen("2.out","w",stdout);
  while (1) {
    scanf("%d %d %d", &n, &m, &q);
    if (n == 0 && m == 0 && q == 0)
      break;
    N = sqrt(n);
    M = sqrt(m);
    if (N * N < n)
      N++;
    if (M * M < m)
      M++;
    int x;
    tot = N * N;
    tp = M * M;
    for (int i = 0; i < tot * tp; i++)
      mp[i] = int_max;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        scanf("%d", &mp[i * tp + j]);
      }
    }
    for (int i = 0; i < N; i++)
      for (int j = 0; j < M; j++) {
        int va = i * M + j, x = i * N, y = j * M;
        for (int k = 0; k < N; k++)
          rmq_r[va][k] = int_max;
        for (int k = 0; k < M; k++)
          rmq_c[va][k] = int_max;
        for (int k = 0; k < N; k++)
          for (int p = 0; p < M; p++) {
            rmq_r[va][k] = min(rmq_r[va][k], mp[(x + k) * tp + y + p]);
            rmq_c[va][p] = min(rmq_c[va][p], mp[(x + k) * tp + y + p]);
          }
      }

    int x_1, y_1, x_2, y_2;
    //	printf("%d %d\\n",N,M);
    for (int i = 0; i < q; i++) {
      scanf("%d %d %d %d", &x_1, &y_1, &x_2, &y_2);
      int ans = int_max;

      int sx_1 = x_1 / N, sx_2 = x_2 / N;
      int sy_1 = y_1 / M, sy_2 = y_2 / M;

      if (sx_1 == sx_2 && sy_1 == sy_2) {

        for (int k = x_1; k <= x_2; k++)
          for (int p = y_1; p <= y_2; p++) {
            ans = min(ans, mp[k * tp + p]);
          }
        printf("%d\\n", ans);
      } else if (sx_1 == sx_2) {

        printf("%d\\n", gaor(x_1, y_1, x_2, y_2));
      } else if (sy_1 == sy_2) {

        printf("%d\\n", gaoc(x_1, y_1, x_2, y_2));
      } else {
        // puts("a");
        for (int i = sx_1 + 1; i < sx_2; i++)
          for (int j = sy_1 + 1; j < sy_2; j++) {
            ans = min(ans, rmq_findr(i * M + j, 0, N - 1));
          }
        // puts("a");
        // printf("%d\\n",ans);
        ans = min(ans, gaor(x_1, y_1, (sx_1 + 1) * N - 1, y_2));

        ans = min(ans, gaor(sx_2 * N, y_1, x_2, y_2)); // printf("%d\\n",ans);
        ans = min(ans,
                  gaoc((sx_1 + 1) * N, y_1, sx_2 * N - 1, (sy_1 + 1) * M - 1));
        ans = min(ans, gaoc((sx_1 + 1) * N, sy_2 * M, sx_2 * N - 1, y_2));
        printf("%d\\n", ans);
      }
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
#include <string.h>
#define M 1000000
#define inf 0x7FFFFFFF
using namespace std;

int arr[M + 10], dat[M + 10], p[M + 10], LOG[M + 10];
int dp[250010][19];
void init_rmq(int n, int dp[][19], int dt[]) {
  for (int i = 0; i < n; i++)
    dp[i][0] = dt[i];
  int k = LOG[n] / LOG[2];
  for (int i = 1; i <= k; i++)
    for (int j = 0; j < n; j++)
      if (j + p[i - 1] < n)
        dp[j][i] = min(dp[j][i - 1], dp[j + p[i - 1]][i - 1]);
      else
        dp[j][i] = dp[j][i - 1];
}
int query_rmq(int a, int b, int dp[][19]) {
  int x = a, y = b;
  if (x > y)
    swap(x, y);
  int k = LOG[y - x + 1] / LOG[2];
  return min(dp[x][k], dp[y - p[k] + 1][k]);
}

int main() {
  p[0] = 1;
  for (int i = 1; i < 19; i++)
    p[i] = p[i - 1] * 2;
  LOG[0] = -1;
  for (int i = 1; i <= M; i++)
    LOG[i] = (i & (i - 1)) ? LOG[i - 1] : LOG[i - 1] + 1;

  int n, m, q;
  while (scanf("%d%d%d", &n, &m, &q), n || m || q) {
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        scanf("%d", &arr[i * m + j]);

    if (n * m > 250000) {
      while (q--) {
        int l1, l2, r1, r2;
        scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
        int ans = inf;
        for (int i = l1; i <= l2; i++)
          for (int j = r1; j <= r2; j++)
            ans = min(ans, arr[i * m + j]);
        printf("%d\\n", ans);
      }
    }

    if (n < m) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++)
          dat[j] = arr[i * m + j];
        init_rmq(m, dp + i * m, dat);
      }
      while (q--) {
        int l1, l2, r1, r2;
        scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
        int ans = inf;
        for (int i = l1; i <= l2; i++)
          ans = min(ans, query_rmq(r1, r2, dp + i * m));
        printf("%d\\n", ans);
      }
    } else {
      for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++)
          dat[j] = arr[j * m + i];
        init_rmq(n, dp + i * n, dat);
      }
      while (q--) {
        int l1, l2, r1, r2;
        scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
        int ans = inf;
        for (int i = r1; i <= r2; i++)
          ans = min(ans, query_rmq(l1, l2, dp + i * n));
        printf("%d\\n", ans);
      }
    }
  }
  return 0;
}