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

// 洛谷P1919
#include <bits/stdc++.h>
#include <complex>
using namespace std;

const int N = 3e6 + 10;
const long double PI = acos(-1);
typedef complex<long double> Complex;
struct FastFourierTransform {
  Complex omega[N], omegaInverse[N];
  void init(int n) {
    for (int i = 0; i < n; ++i) {
      omega[i] = Complex(cos(2 * PI / n * i), sin(2 * PI / n * i));
      omegaInverse[i] = conj(omega[i]);
    }
  }
  void transform(Complex *a, int n, const Complex *omega) {
    for (int i = 0, j = 0; i < n; ++i) {
      if (i > j)
        swap(a[i], a[j]);
      for (int l = n >> 1; (j ^= l) < l; l >>= 1)
        ;
    }
    for (int l = 2; l <= n; l <<= 1) {
      int m = l >> 1;
      for (Complex *p = a; p != a + n; p += l)
        for (int i = 0; i < m; ++i) {
          Complex t = omega[n / l * i] * p[m + i];
          p[m + i] = p[i] - t;
          p[i] += t;
        }
    }
  }
  void dft(Complex *a, int n) { transform(a, n, omega); }
  void idft(Complex *a, int n) { // 逆变换
    transform(a, n, omegaInverse);
    for (int i = 0; i < n; ++i)
      a[i] /= n;
  }
} fft;
Complex a[N];

typedef long long ll;
ll P = 200003;
ll c[N];
int idx[200003];
int Pow[200003];

int main() {
  ll tmp = 1;
  for (int i = 0; i <= P - 2; ++i) {
    idx[tmp] = i;
    Pow[i] = tmp;
    tmp = tmp * 2 % P;
  }
  int n;
  scanf("%d", &n);
  ll ans = 0;
  for (int i = 0; i < n; ++i) {
    scanf("%lld", c + i);
    if (c[i] == 0)
      continue;
    a[idx[c[i]]] += Complex(1, 0), ans -= c[i] * c[i] % P;
  }

  tmp = 1;
  n = 2 * P;
  while (tmp < n)
    tmp <<= 1;
  n = tmp;
  fft.init(n);
  fft.dft(a, n);
  for (int i = 0; i < n; ++i)
    a[i] *= a[i];
  fft.idft(a, n);

  for (int i = 0; i < n; ++i) {
    ans += (ll)(a[i].real() + 0.5) * Pow[i % (P - 1)];
  }

  ans /= 2;
  printf("%lld", ans);
  return 0;
}
/*
3
2019 2020 200002
*/

Error: -6
double free or corruption (out)


Fixed submission:

#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
typedef unsigned long long ull;
#define pb(x) push_back(x)
vector<int> str[N];
vector<ull> ha[N];

ull base[N];
map<ull, vector<int>> mp;
int cnt[26];
ull GetHash(int i, int x, int y) {
  return ha[i][y] - ha[i][x - 1] * base[y - x + 1];
}
int main() {
  base[0] = 1;
  for (int i = 1; i < N; ++i)
    base[i] = base[i - 1] * 133331;
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    str[i].pb(0);
    int ch;
    do {
      ch = getchar();
    } while (isspace(ch));
    do {
      str[i].pb(ch - 'a');
    } while (!isspace(ch = getchar()));
    ha[i].resize(str[i].size(), 0);

    for (int j = 1; j < str[i].size(); ++j) {
      ha[i][j] = ha[i][j - 1] * 133331 + str[i][j] + 17;
    }
    ull hash;
    if (str[i].size() == 2)
      hash = 0;
    else
      hash = GetHash(i, 2, str[i].size() - 1);

    if (mp.find(hash) == mp.end())
      mp[hash] = vector<int>(26, 0);
    ++mp[hash][str[i][1]];
  }
  ull ans = 0;
  for (int i = 1; i <= n; ++i) {
    memset(cnt, 0, sizeof(cnt));
    for (unsigned int j = 1; j < str[i].size(); ++j)
      ++cnt[str[i][j]];
    for (unsigned int j = str[i].size(); j > 1; --j) {
      ull hash = 0;
      if (j != str[i].size()) {
        hash = GetHash(i, j, str[i].size() - 1);
        --cnt[str[i][j]];
      }
      if (mp.find(hash) == mp.end())
        continue;
      vector<int> &tmp = mp[hash];
      for (int k = 0; k < 26; ++k)
        if (cnt[k] > 0)
          ans += tmp[k];
    }
  }
  ans -= n;
  printf("%llu", ans);
  return 0;
}