思路

每个单元格 (i,j) 的最终值为 max(r[i], c[j]),总和为所有 max(r[i], c[j]) 的累加。

对列数组 c 排序并计算前缀和,方便快速统计 “小于等于当前行值 r[i] 的列数” 和 “大于当前行值的列的总和”。

遍历每个行值 r[i],通过二分查找找到 c 中第一个大于 r[i] 的位置,从而拆分列数组为 “≤r [i]” 和 “>r [i]” 两部分,分别计算贡献。

#include <bits/stdc++.h>
using namespace std;
#define sc second
#define fr first
#define int long long
#define itn long long
#define vi vector<int>
#define vvi vector<vector<int>>
#define endl '\n'
// const int mod = 998244353;
// const int mod = 1e10 + 7;
int n, m, k, q, x, num, sum = 0, cnt = 0, l = 1, r = 1e10;
string s;
void _()
{
    cin >> n >> m;
    vi r(n);
    for (int i = 0; i < n; ++i)
    {
        cin >> r[i];
    }
    vi c(m);
    for (int i = 0; i < m; ++i)
    {
        cin >> c[i];
    }
    sort(c.begin(), c.end());
    //这之前都是初始化和排序,不讲了awa
    vector<int> q(m + 1, 0);
    for (int i = 0; i < m; ++i)
    {
        q[i + 1] = q[i] + c[i];//"q"即前缀和的拼音首字母,记录前缀和
    }
    int tot = 0;
    for (int i : r)//一行一行的找,一行一行的加
    {
        int pos = upper_bound(c.begin(), c.end(), i) - c.begin();//直接调用函数去找恰好比r[i]大的位置
        tot += (i * pos + (q[m] - q[pos]));//看看这一行里,哪些是比r[i]小的,小的话就换成r[i]并且计入,否则就是c本身(此处用前缀和计算比r[i]大的部分的总和)
    }
    cout << tot << endl;
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int awa = 1;
    // cin >> awa;
    while (awa--)
    {
        _();
    }
    return 0;
}

喜欢的话请点个赞吧awa

(题外话:我看着这c嘎嘎的题解没有这就给补上了)