Problem p02904 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

const int MOD = 1000000007;
const int MOD2 = 1000000009;
const int MAXN = 100000;
int n, k;
int p[MAXN];
int pw[MAXN];
int pw2[MAXN];
int p1[MAXN];
int p2[MAXN];
pair<int, int> tree[4 * MAXN];
int len[4 * MAXN];

void upd(int i, int l, int r, int x, bool add) {
  if (l > x || r < x)
    return;
  if (l == r) {
    if (add) {
      tree[i] = make_pair(x, x);
      len[i] = 1;
    } else {
      tree[i] = {0, 0};
      len[i] = 0;
    }
    return;
  }
  upd(i * 2 + 1, l, (l + r) / 2, x, add);
  upd(i * 2 + 2, (l + r) / 2 + 1, r, x, add);
  len[i] = len[i * 2 + 1] + len[i * 2 + 2];
  tree[i].first = (tree[i * 2 + 1].first +
                   (pw[len[i * 2 + 1]] * 1ll * tree[i * 2 + 2].first)) %
                  MOD;
  tree[i].second = (tree[i * 2 + 1].second +
                    (pw2[len[i * 2 + 1]] * 1ll * tree[i * 2 + 2].second)) %
                   MOD2;
}

set<pair<int, int>> perms;
void solve(int i) {
  if (i + k > n)
    return;
  long long ans2 = p2[n - 1];
  long long ans1 = p1[n - 1];
  ans1 -= p1[i + k - 1];
  ans2 -= p2[i + k - 1];
  if (i) {
    ans1 += p1[i - 1];
    ans2 += p2[i - 1];
    upd(0, 1, n, p[i + k - 1], true);
    upd(0, 1, n, p[i - 1], false);
  } else {
    for (int j = 0; j < k; j++) {
      upd(0, 1, n, p[j], true);
    }
  }
  while (ans1 < 0)
    ans1 += MOD;
  while (ans2 < 0)
    ans2 += MOD2;
  pair<int, int> res;
  res.first = (ans1 + tree[0].first * 1ll * pw[i]) % MOD;
  res.second = (ans2 + tree[0].second * 1ll * pw2[i]) % MOD2;
  perms.insert(res);
}
int main() {
  pw[0] = 1;
  pw2[0] = 1;
  for (int i = 1; i < MAXN; i++) {
    pw[i] = (MAXN * 1ll * pw[i - 1]) % MOD;
    pw2[i] = (MAXN * 1ll * pw2[i - 1]) % MOD2;
  }
  scanf("%d %d", &n, &k);
  for (int i = 0; i < n; i++) {
    scanf("%d", p + i);
    p[i]++;
    p1[i] = (p[i] * 1ll * pw[i] + p1[i - 1]) % MOD;
    p2[i] = (p[i] * 1ll * pw2[i] + p2[i - 1]) % MOD2;
  }
  for (int i = 0; i < n; i++)
    solve(i);
  printf("%d\n", perms.size());
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int MOD = 1000000007;
const int MOD2 = 1000000009;
const int MAXN = 200005;
int n, k;
int p[MAXN];
int pw[MAXN];
int pw2[MAXN];
int p1[MAXN];
int p2[MAXN];
pair<int, int> tree[4 * MAXN];
int len[4 * MAXN];

void upd(int i, int l, int r, int x, bool add) {
  if (l > x || r < x)
    return;
  if (l == r) {
    if (add) {
      tree[i] = make_pair(x, x);
      len[i] = 1;
    } else {
      tree[i] = {0, 0};
      len[i] = 0;
    }
    return;
  }
  upd(i * 2 + 1, l, (l + r) / 2, x, add);
  upd(i * 2 + 2, (l + r) / 2 + 1, r, x, add);
  len[i] = len[i * 2 + 1] + len[i * 2 + 2];
  tree[i].first = (tree[i * 2 + 1].first +
                   (pw[len[i * 2 + 1]] * 1ll * tree[i * 2 + 2].first)) %
                  MOD;
  tree[i].second = (tree[i * 2 + 1].second +
                    (pw2[len[i * 2 + 1]] * 1ll * tree[i * 2 + 2].second)) %
                   MOD2;
}

set<pair<int, int>> perms;
void solve(int i) {
  if (i + k > n)
    return;
  long long ans2 = p2[n - 1];
  long long ans1 = p1[n - 1];
  ans1 -= p1[i + k - 1];
  ans2 -= p2[i + k - 1];
  if (i) {
    ans1 += p1[i - 1];
    ans2 += p2[i - 1];
    upd(0, 1, n, p[i + k - 1], true);
    upd(0, 1, n, p[i - 1], false);
  } else {
    for (int j = 0; j < k; j++) {
      upd(0, 1, n, p[j], true);
    }
  }
  while (ans1 < 0)
    ans1 += MOD;
  while (ans2 < 0)
    ans2 += MOD2;
  pair<int, int> res;
  res.first = (ans1 + tree[0].first * 1ll * pw[i]) % MOD;
  res.second = (ans2 + tree[0].second * 1ll * pw2[i]) % MOD2;
  perms.insert(res);
}
int main() {
  pw[0] = 1;
  pw2[0] = 1;
  for (int i = 1; i < MAXN; i++) {
    pw[i] = (MAXN * 1ll * pw[i - 1]) % MOD;
    pw2[i] = (MAXN * 1ll * pw2[i - 1]) % MOD2;
  }
  scanf("%d %d", &n, &k);
  for (int i = 0; i < n; i++) {
    scanf("%d", p + i);
    p[i]++;
    p1[i] = (p[i] * 1ll * pw[i] + p1[i - 1]) % MOD;
    p2[i] = (p[i] * 1ll * pw2[i] + p2[i - 1]) % MOD2;
  }
  for (int i = 0; i < n; i++)
    solve(i);
  printf("%d\n", perms.size());
}