Problem p01140 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;

const int mod = 1000000007;
struct Mod {
public:
  int num;
  Mod() : num(0) { ; }
  Mod(long long int n) : num((n % mod + mod) % mod) { ; }
  Mod(int n) : num((n % mod + mod) % mod) { ; }
  operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) {
  return Mod((mod + a.num - b.num) % mod);
}
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) {
  return Mod(((long long)a.num * b.num) % mod);
}
Mod operator*(const long long int a, const Mod b) { return Mod(a) * b; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
  if (n == 0)
    return Mod(1);
  Mod res = (a * a) ^ (n / 2);
  if (n % 2)
    res = res * a;
  return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
  assert(b.num != 0);
  return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
  assert(b.num != 0);
  return Mod(a) * inv(b);
}
Mod operator/=(Mod &a, const Mod b) {
  assert(b.num != 0);
  return a = a * inv(b);
}

#define MAX_N 1024000

Mod fact[MAX_N], factinv[MAX_N];
void init() {
  fact[0] = Mod(1);
  factinv[0] = 1;
  for (int i = 0; i < MAX_N - 1; ++i) {
    fact[i + 1] = fact[i] * Mod(i + 1);
    factinv[i + 1] = factinv[i] / Mod(i + 1);
  }
}
Mod comb(const int a, const int b) {
  return fact[a] * factinv[b] * factinv[a - b];
}

template <typename T>
vector<vector<T>> keisann(const vector<vector<T>> l,
                          const vector<vector<T>> r) {
  vector<vector<T>> ans(l.size(), vector<T>(r[0].size()));
  assert(l[0].size() == r.size());
  for (unsigned int h = 0; h < l.size(); ++h) {
    for (unsigned int i = 0; i < r.size(); ++i) {
      for (unsigned int w = 0; w < r[0].size(); ++w) {

        ans[h][w] += l[h][i] * r[i][w];
      }
    }
  }
  return ans;
}
template <typename T>
vector<vector<T>> powgyou(vector<vector<T>> a, const long long int n) {
  assert(a.size() == a[0].size());
  if (!n) {
    vector<vector<T>> e(a.size(), vector<T>(a[0].size()));
    for (unsigned int i = 0; i < a.size(); ++i) {
      e[i][i] = 1;
    }
    return e;
  }
  if (n == 1)
    return a;
  else {
    vector<vector<T>> ans(a.size(), vector<T>(a[0].size(), 0));
    ans = powgyou(a, n / 2);
    ans = keisann(ans, ans);
    if (n % 2) {
      ans = keisann(ans, a);
    }
    return ans;
  }
}

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()

const int INF = 2147483647;
const long long int L_INF = 9223372036854775807;

typedef int Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src, int dst, Weight weight) : src(src), dst(dst), weight(weight) {}
};
bool operator<(const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
             e.src != f.src ? e.src < f.src
                            : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;
#define RESIDUE(s, t) (capacity[s][t] - flow[s][t])

vector<pair<int, int>> uses;

// 流量0の逆辺も張らないと正しく求まらないので注意
Weight maximumFlow(const Graph &ag, int s, int t) {

  Graph g(ag);
  for (int i = 0; i < ag.size(); ++i) {
    for (int j = 0; j < ag[i].size(); ++j) {
      int d = ag[i][j].dst;
      int s = ag[i][j].src;

      bool ok = false;
      for (int k = 0; k < ag[d].size(); ++k) {
        if (ag[d][k].src == s) {
          ok = true;
          break;
        }
      }
      if (!ok) {
        g[d].push_back(Edge(d, s, 0));
      }
    }
  }

  int n = g.size();
  Matrix flow(n, Array(n)), capacity(n, Array(n));
  REP(u, n) FOR(e, g[u]) capacity[e->src][e->dst] += e->weight;

  Weight total = 0;
  while (1) {
    queue<int> Q;
    Q.push(s);
    vector<int> prev(n, -1);
    prev[s] = s;
    while (!Q.empty() && prev[t] < 0) {
      int u = Q.front();
      Q.pop();
      FOR(e, g[u]) if (prev[e->dst] < 0 && RESIDUE(u, e->dst) > 0) {
        prev[e->dst] = u;
        Q.push(e->dst);
      }
    }
    if (prev[t] < 0)
      return total; // prev[x] == -1 <=> t-side
    Weight inc = INF;
    for (int j = t; prev[j] != j; j = prev[j])
      inc = min(inc, RESIDUE(prev[j], j));
    for (int j = t; prev[j] != j; j = prev[j])
      flow[prev[j]][j] += inc, flow[j][prev[j]] -= inc;
    total += inc;
  }
}

map<long long int, int> soinnsuu(long long int a) {
  map<long long int, int> ans;
  for (long long i = 2; i * i <= a; ++i) {
    while (a % i == 0) {
      ans[i]++;
      a /= i;
    }
  }
  if (a != 1)
    ans[a]++;

  return ans;
}

bool isso(long long int a) {
  if (a == 1)
    return false;
  for (long long int i = 2; i * i <= a; ++i) {
    if (!(a % i)) {
      return false;
    } else {
    }
  }
  return true;
}

struct vert {
  int deg;
  int s;
  int id;
  vert(int a, int b, int c) {
    deg = a;
    s = b;
    id = c;
  }
};

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;
class Compare {
public:
  bool operator()(const pair<int, int> &l, const pair<int, int> &r) {
    return l.second > r.second;
  }
};

int main() {
  while (1) {
    int N;
    cin >> N;
    int M;
    cin >> M;
    if (!N)
      break;
    vector<int> hs, ws;
    for (int i = 0; i < N; ++i) {
      int h;
      cin >> h;
      hs.push_back(h);
    }
    for (int i = 0; i < M; ++i) {
      int w;
      cin >> w;
      ws.push_back(w);
    }

    map<int, long long int> hnums, wnums;

    for (int u = 0; u <= hs.size() - 1; ++u) {
      int num = 0;
      for (int y = u; y < hs.size(); ++y) {
        num += hs[y];
        hnums[num]++;
      }
    }

    for (int d = 0; d <= ws.size() - 1; ++d) {
      int num = 0;
      for (int x = d; x < ws.size(); ++x) {
        num += ws[x];
        wnums[num]++;
      }
    }

    long long int ans = 0;
    for (auto it = hnums.begin(); it != hnums.end(); ++it) {
      ans += (*it).second * wnums[(*it).first];
    }
    cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;

const int mod = 1000000007;
struct Mod {
public:
  int num;
  Mod() : num(0) { ; }
  Mod(long long int n) : num((n % mod + mod) % mod) { ; }
  Mod(int n) : num((n % mod + mod) % mod) { ; }
  operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) {
  return Mod((mod + a.num - b.num) % mod);
}
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) {
  return Mod(((long long)a.num * b.num) % mod);
}
Mod operator*(const long long int a, const Mod b) { return Mod(a) * b; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
  if (n == 0)
    return Mod(1);
  Mod res = (a * a) ^ (n / 2);
  if (n % 2)
    res = res * a;
  return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
  assert(b.num != 0);
  return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
  assert(b.num != 0);
  return Mod(a) * inv(b);
}
Mod operator/=(Mod &a, const Mod b) {
  assert(b.num != 0);
  return a = a * inv(b);
}

#define MAX_N 1024000

Mod fact[MAX_N], factinv[MAX_N];
void init() {
  fact[0] = Mod(1);
  factinv[0] = 1;
  for (int i = 0; i < MAX_N - 1; ++i) {
    fact[i + 1] = fact[i] * Mod(i + 1);
    factinv[i + 1] = factinv[i] / Mod(i + 1);
  }
}
Mod comb(const int a, const int b) {
  return fact[a] * factinv[b] * factinv[a - b];
}

template <typename T>
vector<vector<T>> keisann(const vector<vector<T>> l,
                          const vector<vector<T>> r) {
  vector<vector<T>> ans(l.size(), vector<T>(r[0].size()));
  assert(l[0].size() == r.size());
  for (unsigned int h = 0; h < l.size(); ++h) {
    for (unsigned int i = 0; i < r.size(); ++i) {
      for (unsigned int w = 0; w < r[0].size(); ++w) {

        ans[h][w] += l[h][i] * r[i][w];
      }
    }
  }
  return ans;
}
template <typename T>
vector<vector<T>> powgyou(vector<vector<T>> a, const long long int n) {
  assert(a.size() == a[0].size());
  if (!n) {
    vector<vector<T>> e(a.size(), vector<T>(a[0].size()));
    for (unsigned int i = 0; i < a.size(); ++i) {
      e[i][i] = 1;
    }
    return e;
  }
  if (n == 1)
    return a;
  else {
    vector<vector<T>> ans(a.size(), vector<T>(a[0].size(), 0));
    ans = powgyou(a, n / 2);
    ans = keisann(ans, ans);
    if (n % 2) {
      ans = keisann(ans, a);
    }
    return ans;
  }
}

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()

const int INF = 2147483647;
const long long int L_INF = 9223372036854775807;

typedef int Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src, int dst, Weight weight) : src(src), dst(dst), weight(weight) {}
};
bool operator<(const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
             e.src != f.src ? e.src < f.src
                            : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;
#define RESIDUE(s, t) (capacity[s][t] - flow[s][t])

vector<pair<int, int>> uses;

// 流量0の逆辺も張らないと正しく求まらないので注意
Weight maximumFlow(const Graph &ag, int s, int t) {

  Graph g(ag);
  for (int i = 0; i < ag.size(); ++i) {
    for (int j = 0; j < ag[i].size(); ++j) {
      int d = ag[i][j].dst;
      int s = ag[i][j].src;

      bool ok = false;
      for (int k = 0; k < ag[d].size(); ++k) {
        if (ag[d][k].src == s) {
          ok = true;
          break;
        }
      }
      if (!ok) {
        g[d].push_back(Edge(d, s, 0));
      }
    }
  }

  int n = g.size();
  Matrix flow(n, Array(n)), capacity(n, Array(n));
  REP(u, n) FOR(e, g[u]) capacity[e->src][e->dst] += e->weight;

  Weight total = 0;
  while (1) {
    queue<int> Q;
    Q.push(s);
    vector<int> prev(n, -1);
    prev[s] = s;
    while (!Q.empty() && prev[t] < 0) {
      int u = Q.front();
      Q.pop();
      FOR(e, g[u]) if (prev[e->dst] < 0 && RESIDUE(u, e->dst) > 0) {
        prev[e->dst] = u;
        Q.push(e->dst);
      }
    }
    if (prev[t] < 0)
      return total; // prev[x] == -1 <=> t-side
    Weight inc = INF;
    for (int j = t; prev[j] != j; j = prev[j])
      inc = min(inc, RESIDUE(prev[j], j));
    for (int j = t; prev[j] != j; j = prev[j])
      flow[prev[j]][j] += inc, flow[j][prev[j]] -= inc;
    total += inc;
  }
}

map<long long int, int> soinnsuu(long long int a) {
  map<long long int, int> ans;
  for (long long i = 2; i * i <= a; ++i) {
    while (a % i == 0) {
      ans[i]++;
      a /= i;
    }
  }
  if (a != 1)
    ans[a]++;

  return ans;
}

bool isso(long long int a) {
  if (a == 1)
    return false;
  for (long long int i = 2; i * i <= a; ++i) {
    if (!(a % i)) {
      return false;
    } else {
    }
  }
  return true;
}

struct vert {
  int deg;
  int s;
  int id;
  vert(int a, int b, int c) {
    deg = a;
    s = b;
    id = c;
  }
};

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;
class Compare {
public:
  bool operator()(const pair<int, int> &l, const pair<int, int> &r) {
    return l.second > r.second;
  }
};

int fri[100][100];
int N, M;

long long int getans(vector<int> be, int now, vector<int> hapiness) {
  if (now == N) {
    return accumulate(hapiness.begin(), hapiness.end(), 0);
  }

  bool canjoin = true;
  long long int ans(getans(be, now + 1, hapiness));

  if (be.size() == 0) {
    be.push_back(now);
    hapiness.push_back(0);
    ans = max(ans, getans(be, now + 1, hapiness));
  } else if (be.size() == 1) {
    be.push_back(now);
    hapiness.push_back(0);
    hapiness[0] = fri[now][be[0]];
    hapiness[1] = fri[now][be[0]];
    ans = max(ans, getans(be, now + 1, hapiness));
  } else {
    int aminhap = 99999999;
    for (int i = 0; i < be.size(); ++i) {
      if (fri[now][be[i]]) {
        aminhap = min(aminhap, fri[now][be[i]]);
        hapiness[i] = min(hapiness[i], fri[now][be[i]]);
      } else {
        canjoin = false;
        break;
      }
    }
    if (canjoin) {

      be.push_back(now);
      hapiness.push_back(aminhap);
      ans = max(ans, getans(be, now, hapiness));
    }
  }

  return ans;
}

int main() {
  while (1) {

    int N;
    cin >> N;
    int M;
    cin >> M;
    if (!N)
      break;
    vector<int> hs, ws;
    for (int i = 0; i < N; ++i) {
      int h;
      cin >> h;
      hs.push_back(h);
    }
    for (int i = 0; i < M; ++i) {
      int w;
      cin >> w;
      ws.push_back(w);
    }

    map<int, long long int> hnums, wnums;

    for (int s = 1; s <= hs.size(); ++s) {
      for (int u = 0; u <= hs.size() - s; ++u) {
        int num = 0;
        for (int y = u; y < u + s; ++y) {
          num += hs[y];
        }
        hnums[num]++;
      }
    }
    for (int s = 1; s <= hs.size(); ++s) {
      for (int d = 0; d <= ws.size() - s; ++d) {
        int num = 0;
        for (int x = d; x < d + s; ++x) {
          num += ws[x];
        }
        wnums[num]++;
      }
    }
    long long int ans = 0;
    for (auto it = hnums.begin(); it != hnums.end(); ++it) {
      ans += (*it).second * wnums[(*it).first];
    }
    cout << ans << endl;
  }
  return 0;
}