Problem p03426 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>

using namespace std;

#define INT_MAX_VALUE 2147483647
#define LONG_LONG_MAX_VALUE 9223372036854775807
#define ll long long
#define ld long double

struct XX {
  int s;
  int t;
  int c;
};

class xxGreater {
public:
  bool operator()(const XX &riLeft, const XX &riRight) const {
    // 第2条件
    if ((riLeft.t) == (riRight.t)) {
      return riLeft.s <
             riRight.s; //<:昇順(小さいものから順番)、>:降順(大きいものから順番)
      // プライオリティキューの場合は > で、top()すると値の小さいものがとれる
    }
    // 第1条件
    return (riLeft.t) < (riRight.t);
  }
};

// map<long long,long long> prime_f(long long n){
//     map<long long,long long>res;
//     for(int i=2;i*i<=n;i++){
//         while(n%i==0){
//             ++res[i];
//             n/=i;
//         }
//     }
//     if(n!=1)res[n]=1;
//     return res;
// }

int n;
// int dat[2*10000000];
// int dat2[2*10000000];
int dat[10];
int dat2[10];

void init(int n_) {
  n = 1;
  while (n < n_)
    n *= 2;
  for (int i = 0; i < 2 * n - 1; i++) {
    dat[i] = 0;
    dat2[i] = 0;
  }
}

void initset(int k, int a) {
  k += n - 1;
  dat[k] = a;
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = dat[k * 2 + 1] + dat[k * 2 + 2];
  }
}

//[a,b)の間を[l,r]区間で比較しアップデート
// 引数のindexに注意
// nは固定。initで計算すみ
// update2(L[i],R[i]+1,0,0,n,D[i]);
void update2(int a, int b, int k, int l, int r,
             int v) { // v更新値、区間は0-index
  if (r <= a || b <= l)
    return;
  if (a <= l && r <= b) {
    dat[k] += dat2[k];
    if (r - l > 1) {
      dat2[k * 2 + 1] += dat2[k] / 2;
      dat2[k * 2 + 1] += dat2[k] / 2;
    }
    dat2[k] = v * (r - l);
    return;
  } else {
    update2(a, b, k * 2 + 1, l, (l + r) / 2, v);
    update2(a, b, k * 2 + 2, (l + r) / 2, r, v);
    return;
  }
}

int query(int a, int b, int k, int l, int r) {
  if (r <= a || b <= l)
    return 0;
  if (a <= l && r <= b) {
    dat[k] += dat2[k];
    if (r - l > 1) {
      dat2[k * 2 + 1] += dat2[k] / 2;
      dat2[k * 2 + 1] += dat2[k] / 2;
    }
    dat2[k] = 0;
    return dat[k];
  } else {
    int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return vl + vr;
  }
}

int main(int argc, const char *argv[]) {
  // scanf("%s",S);
  // scanf("%d",&N);
  // scanf("%lld %lld",&target1,&target2);
  // sscanf(tmp.c_str(),"%dd%d%d",&time[i], &dice[i], &z[i]);
  // getline(cin, target);
  // ifstream ifs("a.txt");//テスト用
  // ifs >> a;
  // ここから

  // 入力高速化
  ios::sync_with_stdio(false);
  cin.tie(0);

  ll H, W, D, Q;
  cin >> H >> W >> D;
  ll A[300][300];
  for (ll i = 0; i < H; i++) {
    for (ll j = 0; j < W; j++) {
      cin >> A[i][j];
    }
  }
  cin >> Q;
  ll l[100000], r[100000];
  for (int i = 0; i < Q; i++) {
    cin >> l[i] >> r[i];
  }
  ll x[90001], y[90001];
  for (ll i = 0; i < H; i++) {
    for (ll j = 0; j < W; j++) {
      x[A[i][j]] = j + 1;
      y[A[i][j]] = i + 1;
    }
  }
  ll tmp[90001];
  for (ll i = 0; i <= D; i++)
    tmp[i] = 0;
  for (ll i = 1; i <= D; i++) {
    ll t = 0;
    for (ll j = i; j < 90000; j = j + D) {
      t += abs(x[j + D] - x[j]) + abs(y[j + D] - y[j]);
      tmp[j + D] = t;
    }
  }

  for (int i = 0; i < Q; i++) {
    ll ans = tmp[r[i]] - tmp[l[i]];
    cout << ans << endl;
  }

  // ここまで
  // cout << "ans" << endl;改行含む
  // printf("%.0f\n",ans);//小数点以下表示なし
  // printf("%.7f\n",p);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>

using namespace std;

#define INT_MAX_VALUE 2147483647
#define LONG_LONG_MAX_VALUE 9223372036854775807
#define ll long long
#define ld long double

struct XX {
  int s;
  int t;
  int c;
};

class xxGreater {
public:
  bool operator()(const XX &riLeft, const XX &riRight) const {
    // 第2条件
    if ((riLeft.t) == (riRight.t)) {
      return riLeft.s <
             riRight.s; //<:昇順(小さいものから順番)、>:降順(大きいものから順番)
      // プライオリティキューの場合は > で、top()すると値の小さいものがとれる
    }
    // 第1条件
    return (riLeft.t) < (riRight.t);
  }
};

// map<long long,long long> prime_f(long long n){
//     map<long long,long long>res;
//     for(int i=2;i*i<=n;i++){
//         while(n%i==0){
//             ++res[i];
//             n/=i;
//         }
//     }
//     if(n!=1)res[n]=1;
//     return res;
// }

int n;
// int dat[2*10000000];
// int dat2[2*10000000];
int dat[10];
int dat2[10];

void init(int n_) {
  n = 1;
  while (n < n_)
    n *= 2;
  for (int i = 0; i < 2 * n - 1; i++) {
    dat[i] = 0;
    dat2[i] = 0;
  }
}

void initset(int k, int a) {
  k += n - 1;
  dat[k] = a;
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = dat[k * 2 + 1] + dat[k * 2 + 2];
  }
}

//[a,b)の間を[l,r]区間で比較しアップデート
// 引数のindexに注意
// nは固定。initで計算すみ
// update2(L[i],R[i]+1,0,0,n,D[i]);
void update2(int a, int b, int k, int l, int r,
             int v) { // v更新値、区間は0-index
  if (r <= a || b <= l)
    return;
  if (a <= l && r <= b) {
    dat[k] += dat2[k];
    if (r - l > 1) {
      dat2[k * 2 + 1] += dat2[k] / 2;
      dat2[k * 2 + 1] += dat2[k] / 2;
    }
    dat2[k] = v * (r - l);
    return;
  } else {
    update2(a, b, k * 2 + 1, l, (l + r) / 2, v);
    update2(a, b, k * 2 + 2, (l + r) / 2, r, v);
    return;
  }
}

int query(int a, int b, int k, int l, int r) {
  if (r <= a || b <= l)
    return 0;
  if (a <= l && r <= b) {
    dat[k] += dat2[k];
    if (r - l > 1) {
      dat2[k * 2 + 1] += dat2[k] / 2;
      dat2[k * 2 + 1] += dat2[k] / 2;
    }
    dat2[k] = 0;
    return dat[k];
  } else {
    int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return vl + vr;
  }
}

int main(int argc, const char *argv[]) {
  // scanf("%s",S);
  // scanf("%d",&N);
  // scanf("%lld %lld",&target1,&target2);
  // sscanf(tmp.c_str(),"%dd%d%d",&time[i], &dice[i], &z[i]);
  // getline(cin, target);
  // ifstream ifs("a.txt");//テスト用
  // ifs >> a;
  // ここから

  // 入力高速化
  ios::sync_with_stdio(false);
  cin.tie(0);

  ll H, W, D, Q;
  cin >> H >> W >> D;
  ll A[300][300];
  for (ll i = 0; i < H; i++) {
    for (ll j = 0; j < W; j++) {
      cin >> A[i][j];
    }
  }
  cin >> Q;
  ll l[100000], r[100000];
  for (int i = 0; i < Q; i++) {
    cin >> l[i] >> r[i];
  }
  ll x[90001], y[90001];
  for (ll i = 0; i < H; i++) {
    for (ll j = 0; j < W; j++) {
      x[A[i][j]] = j + 1;
      y[A[i][j]] = i + 1;
    }
  }
  ll tmp[90001];
  for (ll i = 0; i <= D; i++)
    tmp[i] = 0;
  for (ll i = 1; i <= D; i++) {
    ll t = 0;
    for (ll j = i; j + D < 90001; j = j + D) {
      t += abs(x[j + D] - x[j]) + abs(y[j + D] - y[j]);
      tmp[j + D] = t;
    }
  }

  for (int i = 0; i < Q; i++) {
    ll ans = tmp[r[i]] - tmp[l[i]];
    cout << ans << endl;
  }

  // ここまで
  // cout << "ans" << endl;改行含む
  // printf("%.0f\n",ans);//小数点以下表示なし
  // printf("%.7f\n",p);

  return 0;
}