#include using namespace std; const int N = 1e5 + 10; int sum[N], g[N], h[N]; struct Node { int b; // 距离的疲劳值 int s; // 推销的疲劳值 } a[N]; bool cmp(Node &X, const Node &Y) { return X.s > Y.s; // 按推销疲劳值从大到小排序 } int main() { int n; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i].b; // 距离的疲劳值 for (int i = 1; i <= n; i++) cin >> a[i].s; // 推销的疲劳值 sort(a + 1, a + n + 1, cmp); for (int i = 1; i <= n; i++) { sum[i] += sum[i - 1] + a[i].s; // 前缀和处理 算出推销疲劳值最大的前i个人的疲劳值总和 g[i] = max(g[i - 1], 2 * a[i].b); // 求出前i个人的最大距离 } for (int i = n; i >= 1; i--) { h[i] = max(h[i + 1], 2 * a[i].b + a[i].s); // 求出 后i个人的距离推销综合最大值 // 因为舍去了推销疲劳最小的人来让总大 // 所以这里跟q[n]求法不一样 } /* 黄海点评: 1、这里的h[i]挺有意思的,它是指,从i~n中贡献值最大是多少,注意是从i开始,1~i-1的不在范围内讨论 2、i~n中的房子,从距离上来讲,可能是出现在sum[i-1]前面的,但这并不影响, 因为即使遍历到了这样的房子,max也不会变大,也就是此题精妙的地方。 */ for (int i = 1; i <= n; i++) { int res = max(sum[i] + g[i], sum[i - 1] + h[i]); // 前n个人加上了前n个的最大距离疲劳 // 后舍去后的则不加 ,而是加上后n个人的综合最大 , cout << res << endl; } return 0; }