提出 #71734973
ソースコード 拡げる
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
using i128 = __int128_t;
static const int64 INF64 = (1LL<<62);
struct Solver {
int N;
vector<int64> A; // 2N
vector<int64> B; // N
vector<int64> X; // N (upper rows)
vector<int64> Y; // N (columns)
vector<int> ord; // upper rows sorted by X/A
vector<int64> prefSX; // prefix sum X along ord
vector<int64> prefAU; // prefix sum A(upper) along ord
vector<int64> lowPref; // sum of k largest A in lower half
int64 Atot;
vector<int> opt_t; // t*(k)
vector<int64> best_cost; // best cost for each k
Solver(int n,
vector<int64> A_,
vector<int64> B_,
vector<int64> X_,
vector<int64> Y_)
: N(n), A(move(A_)), B(move(B_)), X(move(X_)), Y(move(Y_)) {
build();
}
void build() {
Atot = 0;
for (auto v: A) Atot += v;
ord.resize(N);
iota(ord.begin(), ord.end(), 0);
sort(ord.begin(), ord.end(), [&](int i, int j){
// compare X[i]/A[i] < X[j]/A[j] as X[i]*A[j] < X[j]*A[i]
i128 lhs = (i128)X[i] * (i128)A[j];
i128 rhs = (i128)X[j] * (i128)A[i];
if (lhs != rhs) return lhs < rhs;
return i < j;
});
prefSX.assign(N+1, 0);
prefAU.assign(N+1, 0);
for (int t = 1; t <= N; t++) {
int i = ord[t-1];
prefSX[t] = prefSX[t-1] + X[i];
prefAU[t] = prefAU[t-1] + A[i];
}
vector<int64> lower;
lower.reserve(N);
for (int i = N; i < 2*N; i++) lower.push_back(A[i]);
sort(lower.begin(), lower.end(), greater<int64>());
lowPref.assign(N+1, 0);
for (int k = 1; k <= N; k++) lowPref[k] = lowPref[k-1] + lower[k-1];
opt_t.assign(N+1, 0);
best_cost.assign(N+1, INF64);
}
// D&C optimization with safe SAT/LIN/VAR classification.
// We pass down only currently-variable columns; fixed contributions are accumulated.
void dc_opt(int kL, int kR, int tL, int tR,
const vector<int>& cols,
i128 satSumB_acc,
int64 linCnt_acc,
int64 linSumY_acc) {
if (kL > kR) return;
// Safe bounds in this node:
// k in [kL,kR], S in [SX(tL), SX(tR)]
int64 Smin = prefSX[tL];
int64 Smax = prefSX[tR];
i128 satSumB = satSumB_acc;
int64 linCnt = linCnt_acc;
int64 linSumY = linSumY_acc;
vector<int> varCols;
varCols.reserve(cols.size());
for (int j : cols) {
i128 Amin = (i128)Smin + (i128)kL * (i128)Y[j];
i128 Amax = (i128)Smax + (i128)kR * (i128)Y[j];
if (Amin >= (i128)B[j]) {
// always saturated: contributes Bj
satSumB += (i128)B[j];
} else if (Amax < (i128)B[j]) {
// always linear: contributes S + kYj
linCnt += 1;
linSumY += Y[j];
} else {
// may change: keep variable
varCols.push_back(j);
}
}
int mid = (kL + kR) >> 1;
// ----- Build a structure for VAR at fixed k=mid -----
int m = (int)varCols.size();
vector<int64> C(m);
int64 sumYvar = 0;
for (int idx = 0; idx < m; idx++) {
int j = varCols[idx];
sumYvar += Y[j];
// min(Bj, S + kYj) = kYj + min(Bj - kYj, S)
C[idx] = B[j] - 1LL * mid * Y[j];
}
sort(C.begin(), C.end());
vector<i128> prefC(m+1);
prefC[0] = 0;
for (int i = 0; i < m; i++) prefC[i+1] = prefC[i] + (i128)C[i];
// Scan t in [tL..tR] and evaluate cost(mid,t) fast using two-pointer on sorted C.
int bestT = tL;
int64 bestV = INF64;
int p = 0; // count of C <= S
for (int t = tL; t <= tR; t++) {
int64 S = prefSX[t];
while (p < m && C[p] <= S) p++;
// sum_{var} min(C, S) = prefC[p] + (m-p)*S
i128 sumMinC = prefC[p] + (i128)(m - p) * (i128)S;
// phi = sat + lin + var
// lin: linCnt*S + mid*linSumY
// var: mid*sumYvar + sumMinC
i128 phi = satSumB
+ (i128)linCnt * (i128)S
+ (i128)mid * (i128)linSumY
+ (i128)mid * (i128)sumYvar
+ sumMinC;
i128 base = (i128)Atot - (i128)prefAU[t] - (i128)lowPref[mid];
i128 ans128 = base + phi;
int64 v;
if (ans128 > (i128)INF64) v = INF64;
else if (ans128 < (i128)-INF64) v = -INF64;
else v = (int64)ans128;
if (v < bestV) {
bestV = v;
bestT = t;
}
}
opt_t[mid] = bestT;
best_cost[mid] = bestV;
// Recurse; only varCols remain relevant; accumulated (sat, lin) are fixed.
dc_opt(kL, mid - 1, tL, bestT, varCols, satSumB, linCnt, linSumY);
dc_opt(mid + 1, kR, bestT, tR, varCols, satSumB, linCnt, linSumY);
}
int64 solve() {
vector<int> allCols(N);
iota(allCols.begin(), allCols.end(), 0);
dc_opt(0, N, 0, N, allCols, (i128)0, 0, 0);
int64 ans = INF64;
for (int k = 0; k <= N; k++) ans = min(ans, best_cost[k]);
return ans;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<int64> A(2*N), B(N), X(N), Y(N);
for (int i = 0; i < 2*N; i++) cin >> A[i];
for (int j = 0; j < N; j++) cin >> B[j];
for (int i = 0; i < N; i++) cin >> X[i];
for (int j = 0; j < N; j++) cin >> Y[j];
Solver solver(N, A, B, X, Y);
cout << solver.solve() << "\n";
return 0;
}
提出情報
| 提出日時 |
|
| 問題 |
E - Large Board |
| ユーザ |
apiad |
| 言語 |
C++23 (GCC 15.2.0) |
| 得点 |
1500 |
| コード長 |
6064 Byte |
| 結果 |
AC |
| 実行時間 |
519 ms |
| メモリ |
153236 KiB |
ジャッジ結果
| セット名 |
Sample |
All |
| 得点 / 配点 |
0 / 0 |
1500 / 1500 |
| 結果 |
|
|
| セット名 |
テストケース |
| Sample |
00-sample-001.txt, 00-sample-002.txt, 00-sample-003.txt, 00-sample-004.txt |
| All |
00-sample-001.txt, 00-sample-002.txt, 00-sample-003.txt, 00-sample-004.txt, 01-001.txt, 01-002.txt, 01-003.txt, 01-004.txt, 01-005.txt, 01-006.txt, 01-007.txt, 01-008.txt, 01-009.txt, 01-010.txt, 01-011.txt, 01-012.txt, 01-013.txt, 01-014.txt, 01-015.txt, 01-016.txt, 01-017.txt, 01-018.txt, 01-019.txt, 01-020.txt, 01-021.txt, 01-022.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| 00-sample-001.txt |
AC |
1 ms |
3476 KiB |
| 00-sample-002.txt |
AC |
1 ms |
3480 KiB |
| 00-sample-003.txt |
AC |
1 ms |
3512 KiB |
| 00-sample-004.txt |
AC |
1 ms |
3484 KiB |
| 01-001.txt |
AC |
1 ms |
3588 KiB |
| 01-002.txt |
AC |
1 ms |
3484 KiB |
| 01-003.txt |
AC |
2 ms |
3792 KiB |
| 01-004.txt |
AC |
2 ms |
3600 KiB |
| 01-005.txt |
AC |
20 ms |
9596 KiB |
| 01-006.txt |
AC |
49 ms |
12664 KiB |
| 01-007.txt |
AC |
172 ms |
31972 KiB |
| 01-008.txt |
AC |
519 ms |
153236 KiB |
| 01-009.txt |
AC |
299 ms |
51220 KiB |
| 01-010.txt |
AC |
305 ms |
63648 KiB |
| 01-011.txt |
AC |
299 ms |
51208 KiB |
| 01-012.txt |
AC |
406 ms |
72308 KiB |
| 01-013.txt |
AC |
252 ms |
47820 KiB |
| 01-014.txt |
AC |
268 ms |
52124 KiB |
| 01-015.txt |
AC |
300 ms |
56696 KiB |
| 01-016.txt |
AC |
300 ms |
51460 KiB |
| 01-017.txt |
AC |
346 ms |
56988 KiB |
| 01-018.txt |
AC |
277 ms |
50304 KiB |
| 01-019.txt |
AC |
283 ms |
51960 KiB |
| 01-020.txt |
AC |
348 ms |
62584 KiB |
| 01-021.txt |
AC |
252 ms |
45076 KiB |
| 01-022.txt |
AC |
399 ms |
54388 KiB |