#include // {{{ // https://codeforces.com/blog/entry/96344 #pragma GCC optimize("O2,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") using namespace std; template constexpr T MIN = std::numeric_limits::min(); template constexpr T MAX = std::numeric_limits::max(); template [[nodiscard]] static T sc(auto&& x) { return static_cast(x); } template [[nodiscard]] static T sz(auto&& x) { return static_cast(x.size()); } #define prln(...) std::println(__VA_ARGS__) #define pr(...) std::print(__VA_ARGS__) #ifdef LOCAL #define dbgln(...) std::println(__VA_ARGS__) #define dbg(...) std::print(__VA_ARGS__) #endif using ll = long long; using ld = long double; template using v = std::vector; template using r = std::array; template using p = std::pair; #define ff first #define ss second #define eb emplace_back #define pb push_back #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() // }}} template struct segment_tree { public: explicit segment_tree(std::vector const& ts) : n(ts.size()) { tree.resize(4 * n); build(1, 0, n - 1, ts); } [[nodiscard]] T const query(int const l, int const r) const { if (!(0 <= l && l <= r && r < static_cast(n))) { throw std::out_of_range( "cannot query segment tree of size " + std::to_string(n) + " at range [" + std::to_string(l) + ", " + std::to_string(r) + "]"); } return query(1, 0, n - 1, l, r); } void update(int i, T const& t) { if (!(0 <= i && i < static_cast(n))) { throw std::out_of_range("cannot update segment tree of size " + std::to_string(n) + " at index " + std::to_string(i)); } update(1, 0, n - 1, i, t); } [[nodiscard]] size_t lower_bound(T const& t) const noexcept { return lower_bound(1, 0, n - 1, t); } [[nodiscard]] size_t upper_bound(T const& t) const noexcept { return upper_bound(1, 0, n - 1, t); } private: inline T const sentinel() const noexcept { return MIN; } inline T const merge(T const& x, T const& y) const noexcept { return max(x, y); } void build(size_t const node, size_t const l, size_t const r, std::vector const& ts) noexcept { if (l == r) { tree[node] = ts[l]; } else { int m = l + (r - l) / 2; build(2 * node, l, m, ts); build(2 * node + 1, m + 1, r, ts); tree[node] = merge(tree[2 * node], tree[2 * node + 1]); } } [[nodiscard]] T query(size_t const node, size_t const lower, size_t const upper, size_t const l, size_t const r) const noexcept { if (upper < l || r < lower) { return sentinel(); } if (l <= lower && upper <= r) { return tree[node]; } size_t m = lower + (upper - lower) / 2; return merge(query(2 * node, lower, m, l, r), query(2 * node + 1, m + 1, upper, l, r)); } void update(size_t const node, size_t const l, size_t const r, size_t const i, T const& t) noexcept { if (l == r) { tree[node] = t; } else { size_t m = l + (r - l) / 2; if (i <= m) { update(2 * node, l, m, i, t); } else { update(2 * node + 1, m + 1, r, i, t); } tree[node] = merge(tree[2 * node], tree[2 * node + 1]); } } [[nodiscard]] size_t lower_bound(size_t const node, size_t const l, size_t const r, T const& t) const noexcept { if (l == r) { return tree[node] >= t ? l : n; } size_t m = l + (r - l) / 2; if (tree[2 * node] >= t) { size_t res = lower_bound(2 * node, l, m, t); if (res < n) return res; } return lower_bound(2 * node + 1, m + 1, r, t); } [[nodiscard]] size_t upper_bound(size_t const node, size_t const l, size_t const r, T const& t) const noexcept { if (l == r) { return tree[node] > t ? l : n; } size_t m = l + (r - l) / 2; if (tree[2 * node] > t) { size_t res = upper_bound(2 * node, l, m, t); if (res < n) return res; } return upper_bound(2 * node + 1, m + 1, r, t); } size_t n; std::vector tree; }; void solve() { int n, m; cin >> n >> m; v a(n); for (auto& e : a) cin >> e; segment_tree st(a); while (m--) { ll x; cin >> x; int i = st.lower_bound(x); if (i == n) { cout << 0 << ' '; } else { cout << i + 1 << ' '; st.update(i, a[i] - x); a[i] -= x; } } } int main() { // {{{ cin.tie(nullptr)->sync_with_stdio(false); int t = 1; // cin >> t; while (t--) { solve(); } return 0; } // }}}