Problem p02757 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 100000 + 5;

int n, m, p, blo, len, id[maxn], cnt[maxn];
long long tmp, no[maxn], mp[maxn], ans[maxn], sum[maxn], power[maxn];

char s[maxn];

struct M {
  int l, r, num;
  friend bool operator<(M a, M b) {
    if (id[a.l] != id[b.l])
      return id[a.l] < id[b.l];
    return a.r < b.r;
  }
} q[maxn];

inline int read(void) {
  char ch = getchar();
  int x = 0;
  while (!(ch >= '0' && ch <= '9'))
    ch = getchar();
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  return x;
}

inline void change(int x, int val) {
  x = no[x];
  if (cnt[x] > 1)
    tmp -= 1LL * cnt[x] * (cnt[x] - 1) / 2;
  cnt[x] += val;
  if (cnt[x] > 1)
    tmp += 1LL * cnt[x] * (cnt[x] - 1) / 2;
}

inline int check(char a) {
  int x = a - '0';
  if (p == 2) {
    if (x & 1)
      return 0;
    return 1;
  } else if (p == 5) {
    if (x == 0 || x == 5)
      return 1;
    return 0;
  }
  return 0;
}

inline void solve1(void) {
  for (int i = 1; i <= n; i++)
    sum[i] = sum[i - 1] + check(s[i]) * i, no[i] = no[i - 1] + check(s[i]);
  for (int i = 1, l, r; i <= m; i++)
    l = 1, r = n,
    printf("%lld\n", sum[r] - sum[l - 1] - 1LL * (no[r] - no[l - 1]) * (l - 1));
}

signed main(void) {

  n = read(), p = read(), scanf("%s", s + 1), m = 1, n = strlen(s + 1);
  blo = sqrt(n);
  if (p == 2 || p == 5)
    return solve1(), 0;
  for (int i = 1; i <= n; i++)
    id[i] = (i - 1) / blo + 1;
  power[n] = 1;
  for (int i = 1; i <= m; i++)
    q[i].l = 1, q[i].r = n + 1, q[i].num = i;
  for (int i = n - 1; i >= 1; i--)
    power[i] = 1LL * power[i + 1] * 10 % p;
  for (int i = n; i >= 1; i--)
    no[i] = (no[i + 1] + 1LL * power[i] * (s[i] - '0') % p) % p, mp[i] = no[i];
  mp[n + 1] = 0;
  sort(mp + 1, mp + 1 + n + 1);
  len = unique(mp + 1, mp + n + 1 + 1) - mp - 1;
  sort(q + 1, q + m + 1);
  for (int i = 1; i <= n + 1; i++)
    no[i] = lower_bound(mp + 1, mp + len + 1, no[i]) - mp;
  for (int i = 1, l = 1, r = 0; i <= m; i++) {
    for (; l < q[i].l; l++)
      change(l, -1);
    for (; l > q[i].l; l--)
      change(l - 1, 1);
    for (; r < q[i].r; r++)
      change(r + 1, 1);
    for (; r > q[i].r; r--)
      change(r, -1);
    ans[q[i].num] = tmp;
  }
  for (int i = 1; i <= m; i++)
    printf("%lld\n", ans[i]);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 200000 + 5;

int n, m, p, blo, len, id[maxn], cnt[maxn];
long long tmp, no[maxn], mp[maxn], ans[maxn], sum[maxn], power[maxn];

char s[maxn];

struct M {
  int l, r, num;
  friend bool operator<(M a, M b) {
    if (id[a.l] != id[b.l])
      return id[a.l] < id[b.l];
    return a.r < b.r;
  }
} q[maxn];

inline int read(void) {
  char ch = getchar();
  int x = 0;
  while (!(ch >= '0' && ch <= '9'))
    ch = getchar();
  while (ch >= '0' && ch <= '9')
    x = x * 10 + ch - '0', ch = getchar();
  return x;
}

inline void change(int x, int val) {
  x = no[x];
  if (cnt[x] > 1)
    tmp -= 1LL * cnt[x] * (cnt[x] - 1) / 2;
  cnt[x] += val;
  if (cnt[x] > 1)
    tmp += 1LL * cnt[x] * (cnt[x] - 1) / 2;
}

inline int check(char a) {
  int x = a - '0';
  if (p == 2) {
    if (x & 1)
      return 0;
    return 1;
  } else if (p == 5) {
    if (x == 0 || x == 5)
      return 1;
    return 0;
  }
  return 0;
}

inline void solve1(void) {
  for (int i = 1; i <= n; i++)
    sum[i] = sum[i - 1] + check(s[i]) * i, no[i] = no[i - 1] + check(s[i]);
  for (int i = 1, l, r; i <= m; i++)
    l = 1, r = n,
    printf("%lld\n", sum[r] - sum[l - 1] - 1LL * (no[r] - no[l - 1]) * (l - 1));
}

signed main(void) {

  n = read(), p = read(), scanf("%s", s + 1), m = 1, n = strlen(s + 1);
  blo = sqrt(n);
  if (p == 2 || p == 5)
    return solve1(), 0;
  for (int i = 1; i <= n; i++)
    id[i] = (i - 1) / blo + 1;
  power[n] = 1;
  for (int i = 1; i <= m; i++)
    q[i].l = 1, q[i].r = n + 1, q[i].num = i;
  for (int i = n - 1; i >= 1; i--)
    power[i] = 1LL * power[i + 1] * 10 % p;
  for (int i = n; i >= 1; i--)
    no[i] = (no[i + 1] + 1LL * power[i] * (s[i] - '0') % p) % p, mp[i] = no[i];
  mp[n + 1] = 0;
  sort(mp + 1, mp + 1 + n + 1);
  len = unique(mp + 1, mp + n + 1 + 1) - mp - 1;
  sort(q + 1, q + m + 1);
  for (int i = 1; i <= n + 1; i++)
    no[i] = lower_bound(mp + 1, mp + len + 1, no[i]) - mp;
  for (int i = 1, l = 1, r = 0; i <= m; i++) {
    for (; l < q[i].l; l++)
      change(l, -1);
    for (; l > q[i].l; l--)
      change(l - 1, 1);
    for (; r < q[i].r; r++)
      change(r + 1, 1);
    for (; r > q[i].r; r--)
      change(r, -1);
    ans[q[i].num] = tmp;
  }
  for (int i = 1; i <= m; i++)
    printf("%lld\n", ans[i]);
  return 0;
}