题意,给你两个长度为n的数组a和b,你可以重新排列b,每次会让a的一个数加一或者让b的一个数加一,求最大的min(ai, bi)的连乘。
自己做卡了很久,思路想到了,但没想到他最后不需要模拟交换的,导致代码一直没写出来。
我们肯定要让最大的数和最大的匹配,次大和次大的匹配,依次按大小排名匹配,这样是最大的。
那么,如果值为a[x]的数有很多个,他们可能匹配的数大小不同,如果我们要改一个这样的a[x], 一定是让他带走匹配最大的那个数。只不过这样很不好模拟。。。
我们发现,将a数组排序后记为c数组,那么如果我们每次更改最后一个值等于a[x]的,c依然有序! b数组同理搞一个d数组,这样我们就可以直接算了。 因为b数组的对应位置也是可以匹配到的最大的,它也是有序的,满足我们的思路。
点击查看代码
void solve() {int n, q;std::cin >> n >> q;std::vector<i64> a(n), b(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];}for (int i = 0; i < n; ++ i) {std::cin >> b[i];}auto c = a, d = b;std::sort(c.begin(), c.end());std::sort(d.begin(), d.end());Z ans = 1;for (int i = 0; i < n; ++ i) {ans *= std::min(c[i], d[i]);}std::cout << ans << " ";while (q -- ) {int o, x;std::cin >> o >> x;-- x;if (o == 1) {int p = std::upper_bound(c.begin(), c.end(), a[x]) - c.begin() - 1;if (c[p] < d[p]) {ans = ans / c[p] * (c[p] + 1);}++ a[x];++ c[p];} else {int p = std::upper_bound(d.begin(), d.end(), b[x]) - d.begin() - 1;if (d[p] < c[p]) {ans = ans / d[p] * (d[p] + 1);}++ b[x];++ d[p];}std::cout << ans << " \n"[!q];}
}