結果
問題 | No.2808 Concentration |
ユーザー | silv723 |
提出日時 | 2024-07-06 23:59:05 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 11,195 bytes |
コンパイル時間 | 2,452 ms |
コンパイル使用メモリ | 214,040 KB |
実行使用メモリ | 57,600 KB |
最終ジャッジ日時 | 2024-07-08 17:52:11 |
合計ジャッジ時間 | 34,722 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | WA | - |
testcase_20 | WA | - |
testcase_21 | WA | - |
testcase_22 | WA | - |
testcase_23 | WA | - |
testcase_24 | WA | - |
testcase_25 | WA | - |
testcase_26 | WA | - |
testcase_27 | WA | - |
testcase_28 | WA | - |
testcase_29 | WA | - |
testcase_30 | WA | - |
testcase_31 | WA | - |
testcase_32 | WA | - |
testcase_33 | WA | - |
testcase_34 | WA | - |
testcase_35 | WA | - |
testcase_36 | WA | - |
testcase_37 | WA | - |
testcase_38 | WA | - |
testcase_39 | WA | - |
testcase_40 | WA | - |
testcase_41 | WA | - |
testcase_42 | WA | - |
testcase_43 | WA | - |
testcase_44 | WA | - |
testcase_45 | WA | - |
testcase_46 | WA | - |
testcase_47 | WA | - |
testcase_48 | WA | - |
testcase_49 | WA | - |
testcase_50 | WA | - |
testcase_51 | WA | - |
testcase_52 | AC | 2 ms
5,376 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; /* utility::lazysegtree_utility seg(n): すべて0で初期化されたn要素のsegtree beatsを宣言 seg.set(i, x): ai = x seg.chmin(l, r, x): i ∈ [l, r) に対して ai = min(ai, x) seg.chmax(l, r, x): i ∈ [l, r) に対して ai = max(ai, x) また、chminとchmaxをすることでi ∈ [l, r) に対して ai = x とすることも可能 seg.add(l, r, x): i ∈ [l, r) に対して ai += x seg.get(i): aiを返す seg.get_max(l, r): [l, r)の最大値を返す seg.get_min(l, r): [l, r)の最小値を返す seg.get_sum(l, r): [l, r)の総和を返す seg.max_right_max(l, x): l <= rであって a[r] >= xであるような最小のr(存在しなければn)を返す seg.max_right_min(l, x): l <= rであって a[r] <= xであるような最小のr(存在しなければn)を返す seg.max_right_sum_lq(l, x): l <= rであって a[l] + a[l+1] ... a[r] <= xであるような最小のr(存在しなければn)を返す(累積和が単調じゃないと壊れる) seg.max_right_sum_gq(l, x): l <= rであって a[l] + a[l+1] ... a[r] >= xであるような最小のr(存在しなければn)を返す(累積和が単調じゃないと壊れる) seg.min_left_max(r, x): l <= rであって a[l-1] >= xであるような最大のl(存在しなければ0)を返す seg.min_left_min(r, x): l <= rであって a[l-1] <= xであるような最大のl(存在しなければ0)を返す seg.min_left_sum_lq(r, x): l <= rであって a[l-1] + a[l] ... a[r-1] <= xであるような最大のl(存在しなければ0)を返す(累積和が単調じゃないと壊れる) seg.min_left_sum_gq(r, x): l <= rであって a[l-1] + a[l] ... a[r-1] >= xであるような最大のl(存在しなければ0)を返す(累積和が単調じゃないと壊れる) */ namespace utility{ const long long BINF = 1LL << 61; struct lazysegtree_utility{ const long long second_lowest(long long a, long long a2, long long b, long long b2){ if(a == b) return min(a2, b2); if(a2 <= b) return a2; if(b2 <= a) return b2; return max(a, b); } const long long second_highest(long long a, long long a2, long long b, long long b2){ if(a == b) return max(a2, b2); if(a2 >= b) return a2; if(b2 >= a) return b2; return min(a, b); } struct S{ long long lo, hi, lo2, hi2, sum; unsigned int sz, nlo, nhi; bool fail; S():lo(BINF), lo2(BINF), hi(-BINF), hi2(-BINF), sum(0), sz(0), nlo(0), nhi(0), fail(false){} S(long long x, unsigned int sz_ = 1):lo(x), lo2(BINF), hi(x), hi2(-BINF), sum(x*sz_), sz(sz_), nlo(sz_), nhi(sz_), fail(false){} }; S e(){return S();} S op(S l, S r){ S ret; ret.lo = min(l.lo, r.lo), ret.hi = max(l.hi, r.hi); ret.lo2 = second_lowest(l.lo, l.lo2, r.lo, r.lo2); ret.hi2 = second_highest(l.hi, l.hi2, r.hi, r.hi2); ret.sum = l.sum + r.sum, ret.sz = l.sz + r.sz; ret.nlo = l.nlo * (l.lo <= r.lo) + r.nlo * (r.lo <= l.lo); ret.nhi = l.nhi * (l.hi >= r.hi) + r.nhi * (r.hi >= l.hi); return ret; } struct F{ long long lb, ub, bias; F(long long lb_ = -BINF, long long ub_ = BINF, long long bias_ = 0):lb(lb_), ub(ub_), bias(bias_){} static F chmin(long long x){ return F(-BINF, x, 0LL); } static F chmax(long long x){ return F(x, BINF, 0LL); } static F add(long long x){ return F(-BINF, BINF, x); } }; F composition(F a, F b){ F ret; ret.lb = max(min(b.lb + b.bias, a.ub), a.lb) - b.bias; ret.ub = min(max(b.ub + b.bias, a.lb), a.ub) - b.bias; ret.bias = a.bias + b.bias; return ret; } F id(){return F();} S mapping(F f, S x){ if(x.sz == 0) return e(); if(x.lo == x.hi || f.lb == f.ub || f.lb >= x.hi || f.ub <= x.lo){ return S(min(max(x.lo, f.lb), f.ub) + f.bias, x.sz); } if(x.lo2 == x.hi){ x.lo = x.hi2 = max(x.lo, f.lb) + f.bias; x.hi = x.lo2 = min(x.hi, f.ub) + f.bias; x.sum = x.lo * x.nlo + x.hi * x.nhi; return x; } if(f.lb < x.lo2 && f.ub > x.hi2){ long long nxt_lo = max(x.lo, f.lb), nxt_hi = min(x.hi, f.ub); x.sum += (nxt_lo - x.lo) * x.nlo + (nxt_hi - x.hi) * x.nhi + f.bias * x.sz; x.lo = nxt_lo + f.bias, x.hi = nxt_hi + f.bias, x.lo2 += f.bias, x.hi2 += f.bias; return x; } x.fail = true; return x; } lazysegtree_utility():lazysegtree_utility(0){} explicit lazysegtree_utility(int n):lazysegtree_utility(vector<S>(n, e())){}; explicit lazysegtree_utility(const vector<S> &v):n((int)v.size()){ lg = 1; while((1 << lg) < n) lg++; size = 1 << lg; dat.assign(2*size, e()); lazy.assign(2*size, id()); for(int i = 0; i < n; i++) dat[i+size] = v[i]; for(int i = size - 1; i > 0; i--) update(i); }; void set(int p, S x){ assert(0 <= p && p < n); p += size; for(int i = lg; i > 0; i--) push(p >> i); dat[p] = x; for(int i = 1; i <= lg; i++) update(p >> i); } S get(int p){ assert(0 <= p && p < n); p += size; for(int i = lg; i > 0; i--) push(p >> i); return dat[p]; } S prod(int l, int r){ assert(0 <= l && l <= r && r <= n); if(l == r) return e(); l += size; r += size; for(int i = lg; i >= 1; i--){ if(((l >> i) << i) != l) push(l >> i); if(((r >> i) << i) != r) push((r - 1) >> i); } S sml = e(), smr = e(); while(l < r){ if(l & 1) sml = op(sml, dat[l++]); if(r & 1) smr = op(dat[--r], smr); l >>= 1; r >>= 1; } return op(sml, smr); } long long get_sum(int l, int r){ assert(0 <= l && l <= r && r <= n); return prod(l, r).sum; } long long get_max(int l, int r){ assert(0 <= l && l <= r && r <= n); return prod(l, r).hi; } long long get_min(int l, int r){ assert(0 <= l && l <= r && r <= n); return prod(l, r).lo; } void apply(int p, F f){ assert(0 <= p && p < n); p += size; for(int i = lg; i > 0; i--) push(p >> i); dat[p] = mapping(f, dat[p]); for(int i = 1; i <= lg; i++) update(p >> i); } void apply(int l, int r, F f){ assert(0 <= l && l <= r && r <= n); if(l == r) return; l += size; r += size; for(int i = lg; i > 0; i--){ if(((l >> i) << i) != l) push(l >> i); if(((r >> i) << i) != r) push((r - 1) >> i); } int l2 = l, r2 = r; while(l2 < r2){ if(l2 & 1) all_apply(l2++, f); if(r2 & 1) all_apply(--r2, f); l2 >>= 1, r2 >>= 1; } for(int i = 1; i <= lg; i++){ if(((l >> i) << i) != l) update(l >> i); if(((r >> i) << i) != r) update((r - 1) >> i); } } void chmin(int l, int r, long long x){ assert(0 <= l && l <= r && r <= n); apply(l, r, F::chmin(x)); } void chmin(int p, long long x){ assert(0 <= p && p < n); apply(p, F::chmin(x)); } void chmax(int l, int r, long long x){ assert(0 <= l && l <= r && r <= n); apply(l, r, F::chmax(x)); } void chmax(int p, long long x){ assert(0 <= p && p < n); apply(p, F::chmax(x)); } void add(int l, int r, long long x){ assert(0 <= l && l <= r && r <= n); apply(l, r, F::add(x)); } void add(int p, long long x){ assert(0 <= p && p < n); apply(p, F::add(x)); } template<bool (*g)(S)> int max_right(int l){ return max_right(l, [](S x){return g(x);}); } template<class G> int max_right(int l, G g){ assert(0 <= l && l <= n); assert(g(e())); if(l == n) return n; l += size; for(int i = lg; i >= 1; i--) push(l >> i); S sm = e(); do{ while((l & 1) == 0) l >>= 1; if(!g(op(sm, dat[l]))){ while(l < size){ push(l); l *= 2; if(g(op(sm, dat[l]))){ sm = op(sm, dat[l]); l++; } } return l - size; } sm = op(sm, dat[l]); l++; }while((l & -l) != l); return n; } template <bool (*g)(S)> int min_left(int r){ return min_left(r, [](S x){return g(x);}); } template<class G> int min_left(int r, G g){ assert(0 <= r && r <= n); assert(g(e())); if(r == 0) return 0; r += size; for(int i = lg; i >= 1; i--) push((r - 1) >> i); S sm = e(); do{ r--; while(r > 1 && (r % 2)) r >>= 1; if(!g(op(dat[r], sm))){ while(r < size){ push(r); r *= 2; r++; if(g(op(dat[r], sm))){ sm = op(dat[r], sm); r--; } } return r + 1 - size; } sm = op(dat[r], sm); }while((r & -r) != r); return 0; } int max_right_max(int l, long long target){ return max_right(l, [&](S x){return target > x.hi;}); } int max_right_min(int l, long long target){ return max_right(l, [&](S x){return target < x.lo;}); } int max_right_sum_lq(int l, long long target){ return max_right(l, [&](S x){return target < x.sum;}); } int max_right_sum_gq(int l, long long target){ return max_right(l, [&](S x){return target > x.sum;}); } int min_left_max(int r, long long target){ return min_left(r, [&](S x){return target > x.hi;}); } int min_left_min(int r, long long target){ return min_left(r, [&](S x){return target < x.lo;}); } int min_left_sum_lq(int r, long long target){ return min_left(r, [&](S x){return target < x.sum;}); } int min_left_sum_gq(int r, long long target){ return min_left(r, [&](S x){return target > x.sum;}); } private: void update(int k){dat[k] = op(dat[2 * k], dat[2 * k + 1]);} void all_apply(int k, F f){ dat[k] = mapping(f, dat[k]); if(k < size){ lazy[k] = composition(f, lazy[k]); if(dat[k].fail) push(k), update(k); } } void push(int k) { all_apply(2 * k, lazy[k]); all_apply(2 * k + 1, lazy[k]); lazy[k] = id(); } int n, size, lg; vector<S> dat; vector<F> lazy; }; }; int main(){ int n, s, h; cin >> n >> s >> h; assert(1 <= n && n <= 200000); assert(1 <= s && s <= 1000000000); assert(1 <= h && h <= 1000000000); vector<int> x(n), y(n), z(n); int chx = 0; for(int i = 0; i < n; i++){ cin >> x[i] >> y[i] >> z[i]; assert(chx <= x[i] && x[i] <= 1000000000); assert(x[i] < y[i] && y[i] <= 1000000000); assert(1 <= z[i] && z[i] <= 1000000000); chx = y[i] + 1; } utility::lazysegtree_utility seg(n+1); for(int i = 0; i < n+1; i++) seg.set(i, 0); for(int i = 0; i < n; i++){ if(y[i] - x[i] > s) continue; int l = 0, r = i+1; while(r - l > 1){ int mid = (l+r)/2; if(y[mid-1] <= x[i]-h) l = mid; else r = mid; } seg.chmax(i+1, i+2, seg.get_max(0, r)+z[i]); } cout << seg.get_max(0, n+1) << '\n'; }