Skip to content

Commit 58727d6

Browse files
committed
add range-chmax-range-sum beats
1 parent 3190b45 commit 58727d6

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#define PROBLEM "https://yukicoder.me/problems/no/3314"
2+
#include "../trees/range-chmax-range-sum.hpp"
3+
4+
#include <iostream>
5+
#include <tuple>
6+
#include <vector>
7+
using namespace std;
8+
9+
using RCRS = RangeChmaxRangeSum<long long, (1LL << 60)>;
10+
11+
int main() {
12+
cin.tie(nullptr), ios::sync_with_stdio(false);
13+
14+
int N, K, Q;
15+
cin >> N >> K >> Q;
16+
17+
RCRS::segtree seg(N);
18+
for (int i = 0; i < N; ++i) {
19+
int a;
20+
cin >> a;
21+
seg.set(i, RCRS::Gen(a));
22+
}
23+
24+
vector<tuple<int, int, int>> updates(K);
25+
for (auto &[l, r, x] : updates) cin >> l >> r >> x, --l;
26+
27+
vector<tuple<int, int, long long>> query(Q);
28+
for (auto &[l, r, x] : query) cin >> l >> r >> x, --l;
29+
30+
vector<int> ok(Q, K + 1), ng(Q, -1);
31+
32+
for (int t = 0; t < 15; ++t) {
33+
vector<vector<int>> t2qs(K + 1);
34+
for (int q = 0; q < Q; ++q) {
35+
const int t = (ok.at(q) + ng.at(q)) / 2;
36+
t2qs.at(t).push_back(q);
37+
}
38+
39+
RCRS::segtree tree = seg;
40+
41+
for (int t = 0; t < K + 1; ++t) {
42+
if (t) {
43+
auto [l, r, x] = updates.at(t - 1);
44+
tree.apply(l, r, RCRS::Chmax(x));
45+
}
46+
47+
for (int q : t2qs.at(t)) {
48+
auto [l, r, x] = query.at(q);
49+
(tree.prod(l, r).sum >= x ? ok : ng).at(q) = t;
50+
}
51+
}
52+
}
53+
54+
for (auto t : ok) cout << (t == K + 1 ? -1 : t) << '\n';
55+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#pragma once
2+
#include <algorithm>
3+
#include <type_traits>
4+
#include "../acl_beats.hpp"
5+
6+
// Verified: https://yukicoder.me/problems/no/3314
7+
template <typename Num, Num INF> struct RangeChmaxRangeSum {
8+
static_assert(std::is_signed<Num>::value, "Num must be signed");
9+
10+
struct S {
11+
Num lo, lo2, sum;
12+
unsigned sz, nlo;
13+
bool fail;
14+
S() : lo(INF), lo2(INF), sum(0), sz(0), nlo(0), fail(false) {}
15+
S(Num x, unsigned sz_ = 1)
16+
: lo(x), lo2(INF), sum(Num(x) * sz_), sz(sz_), nlo(sz_), fail(false) {}
17+
};
18+
19+
private:
20+
using F = Num;
21+
RangeChmaxRangeSum() = default;
22+
23+
static Num second_lowest(Num a, Num a2, Num c, Num c2) noexcept { // a < a2, c < c2
24+
return a == c ? std::min(a2, c2) : a2 <= c ? a2 : c2 <= a ? c2 : std::max(a, c);
25+
}
26+
27+
static S op(S l, S r) {
28+
S ret;
29+
ret.lo = std::min(l.lo, r.lo);
30+
ret.lo2 = second_lowest(l.lo, l.lo2, r.lo, r.lo2);
31+
ret.sum = l.sum + r.sum, ret.sz = l.sz + r.sz;
32+
ret.nlo = l.nlo * (l.lo <= r.lo) + r.nlo * (r.lo <= l.lo);
33+
return ret;
34+
}
35+
36+
static S e() { return S{}; }
37+
38+
static F composition(F fnew, F fold) { return std::max(fnew, fold); }
39+
40+
static F id() { return -INF; }
41+
42+
static S mapping(F f, S x) {
43+
if (x.sz == 0) return e();
44+
if (f < x.lo2) {
45+
Num nxt_lo = std::max(x.lo, f);
46+
x.sum += (nxt_lo - x.lo) * x.nlo;
47+
x.lo = nxt_lo;
48+
return x;
49+
}
50+
x.fail = 1;
51+
return x;
52+
}
53+
54+
public:
55+
static F Chmax(Num x) { return x; }
56+
57+
static S Gen(Num x, unsigned sz = 1) { return S{x, sz}; }
58+
59+
using segtree = segtree_beats<S, op, e, F, mapping, composition, id>;
60+
};
61+
/* Usage:
62+
using RCRS = RangeChmaxRangeSum<long long, (1LL << 60)>;
63+
vector<RCRS::S> init;
64+
for (auto a : A) init.push_back(RCRS::Gen(a, 1));
65+
RCRS::segtree tree(init);
66+
67+
tree.apply(l, r, RCRS::Chmax(x));
68+
auto p = tree.prod(l, r);
69+
*/

0 commit comments

Comments
 (0)