https://www.hackerrank.com/contests/university-codesprint-2/challenges/game-of-two-stacks
2つのstack$A, B$が与えられる.どちらのstackからも数字を取ってよい.取った数字の和が$x$より大きくなった時点で失格となる.失格にならずに取った数字の和の最大値を求める.
stackなので$A, B$どちらも上からのみ数字を取ることができる.$v[i] = $上から$i$番目まで取った時の数字の和とすれば,$v$は広義単調増加となる.片方を$i$番目まで取ると決め打ちすると,もう片方からは最大で$x - v[i]$まで取ることができ,これは二分探索で求めることができる.$n, m \leq 10 ^5$なので$O(n log n)$で間に合う.
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,k,n) for(int i=k;i<(int)(n);i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define INF 1<<30
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
int main() {
int g;
cin >> g;
vector<ll> a, b, A, B;
rep(q, g) {
int n, m; ll x;
cin >> n >> m >> x;
a.clear(); b.clear();
a.resize(n); b.resize(m);
rep(i, n) cin >> a[i];
rep(i, m) cin >> b[i];
A = a; B = b;
rep(i, n - 1) A[i+1] += A[i];
rep(i, m - 1) B[i+1] += B[i];
int ans = 0;
rep(i, n + 1) {
ll res = (i ? A[i-1] : 0);
if(res <= x) ans = max(ans, i);
else continue;
ll diff = x - res + 1;
vector<ll>::iterator it = lower_bound(B.begin(), B.end(), diff);
int id = it - B.begin();
if(id == 0) continue;
ans = max(ans, i + id);
}
cout << ans << endl;
}
return 0;
}