Problem p01718 (C++) — buggy submission, verdict: Runtime Error

#include <stdio.h>

typedef long long int llint;

#define DEEP 20

llint seg1[(1 << (DEEP + 1))];
llint seg2[(1 << (DEEP + 1))];

llint gcd(llint a, llint b) {
  if (a % b == 0) {
    return b;
  }
  return gcd(b, a % b);
}

llint sai(llint a, llint b) { return a / gcd(a, b) * b; }

llint d[111111];

#define mod 1000000007

int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 0; i < n; i++) {
    llint w;
    scanf("%lld", &w);
    d[i] = w - 1;
  }
  for (int i = 0; i < n; i++) {
    llint w;
    llint all;
    if (d[i] == i) {
      w = 1;
      all = d[i] + 1;
    } else {
      llint now = i;
      all = now + 1;
      for (int ii = 1; ii <= 50; ii++) {
        now = d[now];
        if (now == i) {
          w = ii;
          break;
        }
        all += now + 1;
      }
    }
    seg1[(1 << DEEP) - 1 + i] = w;
    seg2[(1 << DEEP) - 1 + i] = all % mod;
  }
  for (int i = n; i < (1 << DEEP); i++) {
    seg1[(1 << DEEP) - 1 + i] = 1;
    seg2[(1 << DEEP) - 1 + i] = 0;
  }
  for (int i = (1 << DEEP) - 2; i >= 0; i--) {
    seg1[i] = sai(seg1[i * 2 + 1], seg1[i * 2 + 2]);
    seg2[i] = ((seg1[i] / seg1[i * 2 + 1]) % mod * seg2[i * 2 + 1] % mod +
               (seg1[i] / seg1[i * 2 + 2]) % mod * seg2[i * 2 + 2] % mod) %
              mod;
  }
  for (int k = 0; k < q; k++) {
    llint a, b;
    scanf("%lld%lld", &a, &b);
    llint now1 = (1 << DEEP) + a - 2;
    llint now2 = (1 << DEEP) + b - 2;
    if (now1 != now2) {
      llint gc1 = seg1[now1];
      llint k1 = seg2[now1];
      llint gc2 = seg1[now2];
      llint k2 = seg2[now2];
      while (now1 != now2) {
        llint o1 = (now1 - 1) / 2;
        llint o2 = (now2 - 1) / 2;
        if (o1 == o2) {
          break;
        }
        if (now1 % 2 == 1) {
          llint gc = sai(gc1, seg1[now1 + 1]);
          k1 = ((gc / gc1) % mod * k1 % mod +
                (gc / seg1[now1 + 1]) % mod * seg2[now1 + 1] % mod) %
               mod;
          gc1 = gc;
        }
        if (now2 % 2 == 0) {
          llint gc = sai(gc2, seg1[now2 - 1]);
          k2 = ((gc / gc2) % mod * k2 % mod +
                (gc / seg1[now2 - 1]) % mod * seg2[now2 - 1] % mod) %
               mod;
          gc2 = gc;
        }
        now1 = o1;
        now2 = o2;
      }
      llint w = sai(gc1, gc2);
      llint wq =
          ((w / gc1) % mod * k1 % mod + (w / gc2) % mod * k2 % mod) % mod;
      printf("%lld\\n", wq);
    } else {
      printf("%lld\\n", seg2[now1]);
    }
  }
  return 0;
}

Error: 0

Fixed submission:

#include <stdio.h>

typedef long long int llint;

#define DEEP 15

llint seg1[(1 << (DEEP + 1))];
llint seg2[(1 << (DEEP + 1))];

llint gcd(llint a, llint b) {
  if (a % b == 0) {
    return b;
  }
  return gcd(b, a % b);
}

llint sai(llint a, llint b) { return a / gcd(a, b) * b; }

llint d[100000];

#define mod 1000000007

int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 0; i < n; i++) {
    llint w;
    scanf("%lld", &w);
    d[i] = w - 1;
  }
  for (int i = 0; i < n; i++) {
    llint w;
    llint all;
    if (d[i] == i) {
      w = 1;
      all = d[i] + 1;
    } else {
      llint now = i;
      all = now + 1;
      for (int ii = 1; ii <= 40; ii++) {
        now = d[now];
        if (now == i) {
          w = ii;
          break;
        }
        all += now + 1;
      }
    }
    seg1[(1 << DEEP) - 1 + i] = w;
    seg2[(1 << DEEP) - 1 + i] = all % mod;
  }
  for (int i = n; i < (1 << DEEP); i++) {
    seg1[(1 << DEEP) - 1 + i] = 1;
    seg2[(1 << DEEP) - 1 + i] = 0;
  }
  for (int i = (1 << DEEP) - 2; i >= 0; i--) {
    seg1[i] = sai(seg1[i * 2 + 1], seg1[i * 2 + 2]);
    seg2[i] = (seg1[i] / seg1[i * 2 + 1] * seg2[i * 2 + 1] +
               seg1[i] / seg1[i * 2 + 2] * seg2[i * 2 + 2]) %
              mod;
  }
  for (int k = 0; k < q; k++) {
    llint a, b;
    scanf("%lld%lld", &a, &b);
    llint now1 = (1 << DEEP) + a - 2;
    llint now2 = (1 << DEEP) + b - 2;
    if (now1 != now2) {
      llint gc1 = seg1[now1];
      llint k1 = seg2[now1];
      llint gc2 = seg1[now2];
      llint k2 = seg2[now2];
      while (now1 != now2) {
        llint o1 = (now1 - 1) / 2;
        llint o2 = (now2 - 1) / 2;
        if (o1 == o2) {
          break;
        }
        {
          if (now1 % 2 == 1) {
            llint gc = sai(gc1, seg1[now1 + 1]);
            k1 = ((gc / gc1) * k1 + (gc / seg1[now1 + 1]) * seg2[now1 + 1]) %
                 mod;
            gc1 = gc;
          }
        }
        {
          if (now2 % 2 == 0) {
            llint gc = sai(gc2, seg1[now2 - 1]);
            k2 = ((gc / gc2) * k2 + (gc / seg1[now2 - 1]) * seg2[now2 - 1]) %
                 mod;
            gc2 = gc;
          }
        }
        now1 = o1;
        now2 = o2;
      }
      llint w = sai(gc1, gc2);
      llint wq = (w / gc1 * k1 + w / gc2 * k2) % mod;
      printf("%lld\\n", wq);
    } else {
      printf("%lld\\n", seg2[now1]);
    }
  }
  return 0;
}