This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define int ll
using namespace std;
typedef long long ll;
typedef long double ld;
const int N = (int) 1e5 + 7;
int a[N];
int b[N];
int h;
int w;
struct Fraction {
  ll a;
  ll b;
  Fraction(ll a, ll b) : a(a), b(b) {
  }
};
ld getld(Fraction fr) {
  return (ld)fr.a / (ld)fr.b;
}
bool operator < (Fraction First, Fraction Second) {
  return (ld)First.a / (ld)First.b <= (ld)Second.a / (ld)Second.b;
}
bool operator == (Fraction First, Fraction Second) {
  return (ld)First.a / (ld)First.b == (ld)Second.a / (ld)Second.b;
}
Fraction operator + (Fraction First, ll Second) {
  return Fraction(First.a + Second * First.b, First.b);
}
Fraction operator + (ll Second, Fraction First) {
  return Fraction(First.a + Second * First.b, First.b);
}
Fraction operator - (Fraction First, ll Second) {
  return Fraction(First.a - Second * First.b, First.b);
}
Fraction operator - (ll Second, Fraction First) {
  return Fraction(-First.a + Second * First.b, First.b);
}
Fraction operator * (Fraction First, ll Second) {
  return {First.a * Second, First.b};
}
Fraction operator * (ll First, Fraction Second) {
  return {Second.a * First, Second.b};
}
struct T {
  Fraction val;
  int ind;
  bool type;
};
bool operator == (T a, T b) {
  return a.val.a == b.val.a && a.val.b == b.val.b && a.ind == b.ind && a.type == b.type;
}
bool operator < (T a, T b) {
  if ((a.val == b.val) == false) {
    return a.val < b.val;
  }
  if (a.ind != b.ind) {
    return a.ind < b.ind;
  }
  return a.type < b.type;
}
struct BIT {
  vector<int> aib;
  int n;
  BIT(int nn) {
    n = nn;
    aib.resize(n + 1);
  }
  void update(int x, int val) {
    for (int i = x; i <= n; i += i & -i) {
      aib[i] += val;
    }
  }
  int query(int x) {
    int ret = 0;
    for (int i = x; i >= 1; i -= i & -i) {
      ret += aib[i];
    }
    return ret;
  }
  int getprev(int x) {
    if (query(x - 1) == 0) {
      return -1;
    }
    int need = query(x - 1);
    int sol = 0;
    int sum = 0;
    for (int b = 20; b >= 0; b--) {
      if (sol + (1 << b) < x && sum + aib[sol + (1 << b)] < need) {
        sum += aib[sol + (1 << b)];
        sol += (1 << b);
      }
    }
    return sol + 1;
  }
  int getnext(int x) {
    if (query(n) - query(x) == 0) {
      return -1;
    }
    int need = query(x) + 1;
    int sol = 0;
    int sum = 0;
    for (int b = 20; b >= 0; b--) {
      if (sol + (1 << b) <= n && sum + aib[sol + (1 << b)] < need) {
        sum += aib[sol + (1 << b)];
        sol += (1 << b);
      }
    }
    return sol + 1;
  }
};
signed main() {
  ios::sync_with_stdio(0); cin.tie(0);
  cin >> h >> w;
  for (int i = 1; i <= h; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= w; i++) {
    cin >> b[i];
  }
  set<T> s;
  for (int i = 2; i <= h; i++) {
    Fraction fr = {a[i] - a[i - 1], 1};
    s.insert({fr, i, 0});
  }
  for (int i = 2; i <= w; i++) {
    Fraction fr = {b[i] - b[i - 1], 1};
    s.insert({fr, i, 1});
  }
  BIT lines(h), columns(w);
  for (int i = 1; i <= h; i++) {
    lines.update(i, 1);
  }
  for (int i = 1; i <= w; i++) {
    columns.update(i, 1);
  }
  ll ret = 0;
  while (!s.empty()) {
    auto it = s.end();
    it--;
    T aux = *it;
    s.erase(it);
    if (aux.type == 0) {
      int prv = lines.getprev(aux.ind);
      int nxt = lines.getnext(aux.ind);
      Fraction f = aux.val;
      if (prv != -1 && nxt != -1) {
        lines.update(aux.ind, -1);
        Fraction old = {a[nxt] - a[aux.ind], nxt - aux.ind};
        s.erase({old, nxt, 0});
        Fraction fr = {a[nxt] - a[prv], nxt - prv};
        s.insert({fr, nxt, 0});
      } else if (prv != -1 && nxt == -1) {
        lines.update(aux.ind, -1);
        int lastcol = columns.getprev(w + 1);
        ret += (aux.ind - prv) * b[lastcol];
      } else if (prv == -1 && nxt != -1) {
        lines.update(aux.ind, -1);
        int firstcol = columns.getnext(0);
        ret += (nxt - aux.ind) * b[firstcol];
        Fraction old = {a[nxt] - a[aux.ind], nxt - aux.ind};
        s.erase({old, nxt, 0});
      } else {
        break;
      }
    } else {
      int prv = columns.getprev(aux.ind);
      int nxt = columns.getnext(aux.ind);
      Fraction f = aux.val;
      if (prv != -1 && nxt != -1) {
        columns.update(aux.ind, -1);
        Fraction old = {b[nxt] - b[aux.ind], nxt - aux.ind};
        s.erase({old, nxt, 1});
        Fraction fr = {b[nxt] - b[prv], nxt - prv};
        s.insert({fr, nxt, 1});
      } else if (prv != -1 && nxt == -1) {
        columns.update(aux.ind, -1);
        int lastline = lines.getprev(h + 1);
        ret += (aux.ind - prv) * a[lastline];
      } else if (prv == -1 && nxt != -1) {
        columns.update(aux.ind, -1);
        int firstline = lines.getnext(0);
        ret += (nxt - aux.ind) * a[firstline];
        Fraction old = {b[nxt] - b[aux.ind], nxt - aux.ind};
        s.erase({old, nxt, 1});
      } else {
        break;
      }
    }
  }
  cout << ret << "\n";
  return 0;
}
Compilation message (stderr)
kyoto.cpp: In function 'int main()':
kyoto.cpp:171:16: warning: variable 'f' set but not used [-Wunused-but-set-variable]
  171 |       Fraction f = aux.val;
      |                ^
kyoto.cpp:194:16: warning: variable 'f' set but not used [-Wunused-but-set-variable]
  194 |       Fraction f = aux.val;
      |                ^| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |