結果
| 問題 |
No.1826 Fruits Collecting
|
| コンテスト | |
| ユーザー |
🍮かんプリン
|
| 提出日時 | 2022-01-31 09:12:52 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 420 ms / 2,000 ms |
| コード長 | 4,495 bytes |
| コンパイル時間 | 1,819 ms |
| コンパイル使用メモリ | 183,380 KB |
| 実行使用メモリ | 17,560 KB |
| 最終ジャッジ日時 | 2024-06-11 08:43:35 |
| 合計ジャッジ時間 | 13,007 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 43 |
ソースコード
/**
* @FileName a.cpp
* @Author kanpurin
* @Created 2022.01.31 09:12:44
**/
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
struct P {
ll t,x,v;
bool operator<(P p) {
if (t+x != p.t+p.x)
return t+x < p.t+p.x;
else
return t < p.t;
}
};
template< typename Monoid >
struct DynamicSegmentTree {
private:
struct Node;
using Func = function<Monoid(Monoid,Monoid)>;
using node_ptr = unique_ptr<Node>;
Func F;
Monoid e;
size_t n;
struct Node {
size_t index;
Monoid value,prod;
node_ptr left, right;
Node(size_t index, Monoid value) : index(index),
value(value),
prod(value),
left(nullptr),
right(nullptr) {}
};
void node_update(node_ptr &np) const {
np->prod = F(F(np->left?np->left->prod:e,np->value),
np->right?np->right->prod:e);
}
void _update(node_ptr& t, size_t a, size_t b, size_t p, Monoid &val) const {
if (!t) {
t = make_unique<Node>(p, val);
return;
}
if (t->index == p) {
t->value = val;
node_update(t);
return;
}
size_t c = (a+b)/2;
if (p < c) {
if (t->index < p) swap(t->index,p), swap(t->value,val);
_update(t->left,a,c,p,val);
}
else {
if (p < t->index) swap(p,t->index), swap(val,t->value);
_update(t->right,c,b,p,val);
}
node_update(t);
}
Monoid _get(const node_ptr& t, size_t a, size_t b, size_t l, size_t r) const {
if (!t || b <= l || r <= a) return e;
if (l <= a && b <= r) return t->prod;
size_t c = (a + b) / 2;
Monoid result = _get(t->left, a, c, l, r);
if (l <= t->index && t->index < r) result = F(result, t->value);
return F(result, _get(t->right, c, b, l, r));
}
size_t _binary_search(const node_ptr& t,
size_t a, size_t b,
const function<bool(Monoid)> &f,
Monoid &s,
size_t l, size_t r) {
if (!t || r <= a || b <= l) return n;
if (a <= l && r <= b && !f(F(s,t->prod))) {
s = F(s,t->prod);
return n;
}
size_t ret = _binary_search(t->left,a,b,f,s,l,(r-l)/2+l);
if (ret != n) return ret;
if (a <= t->index) {
s = F(s,t->value);
if (f(s)) return t->index;
}
return _binary_search(t->right,a,b,f,s,(r-l)/2+l,r);
}
void _print(node_ptr& t) {
if (!t) return;
_print(t->left);
_print(t->right);
cout << "[" << t->index << "] : " << t->value << endl;
}
node_ptr root;
public:
DynamicSegmentTree(size_t n,
const Func f,
const Monoid &e) : n(n),F(f),e(e),root(nullptr) {}
void update_query(size_t x, Monoid val) {
assert(x < n);
_update(root, 0, n, x, val);
}
Monoid get_query(size_t l, size_t r) const {
assert(l <= r && r <= n);
return _get(root, 0, n, l, r);
}
size_t binary_search(size_t l, size_t r, const function<bool(Monoid)> &f) {
Monoid s = e;
size_t ret = _binary_search(root,l,r,f,s,0,n);
return ret != n ? ret : -1;
}
Monoid operator[](int x) const {
return get_query(x,x+1);
}
size_t size() {
return n;
}
void print() {
_print(root);
}
};
constexpr long long LLINF = 1e18 + 1;
int main() {
int n;cin >> n;
vector<P> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i].t >> a[i].x >> a[i].v;
}
a.push_back({0,0,0});
n++;
sort(a.begin(), a.end());
DynamicSegmentTree<ll> seg(3LL*1000000000,[](ll x,ll y){return max(x,y);},-LLINF);
for (int i = 0; i < n; i++) {
if (a[i].v == 0) {
seg.update_query(1000000000,0);
continue;
}
ll v = seg.get_query(0,a[i].t-a[i].x+1000000001);
if (seg.get_query(a[i].t-a[i].x+1000000000,a[i].t-a[i].x+1000000001) >= v+a[i].v) continue;
seg.update_query(a[i].t-a[i].x+1000000000,v+a[i].v);
}
cout << seg.get_query(0,3LL*1000000000) << endl;
return 0;
}
🍮かんプリン