結果
| 問題 |
No.1014 competitive fighting
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-03-20 22:30:31 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,588 bytes |
| コンパイル時間 | 2,381 ms |
| コンパイル使用メモリ | 190,096 KB |
| 実行使用メモリ | 17,768 KB |
| 最終ジャッジ日時 | 2024-12-15 06:48:29 |
| 合計ジャッジ時間 | 7,802 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 WA * 1 |
| other | AC * 29 WA * 22 |
ソースコード
#include <bits/stdc++.h>
using namespace std::literals::string_literals;
using i64 = std::int_fast64_t;
using std::cout;
using std::cerr;
using std::endl;
using std::cin;
template<typename T>
std::vector<T> make_v(size_t a){return std::vector<T>(a);}
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
return std::vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
#ifndef INCLUDED_SEGMENT_TREE_HPP
#define INCLUDED_SEGMENT_TREE_HPP
#include <cstdint>
#include <vector>
#include <functional>
template<class Monoid>
class segment_tree {
public:
using T = typename Monoid::value_type;
using size_type = std::uint_fast32_t;
using updator = std::function<T(T)>;
using checker = std::function<bool(T)>;
private:
const size_type size_;
size_type height_;
public:
std::vector<T> data;
private:
const size_type get_height(size_type size) const {
size_type height = 1;
while(1 << height <= size) height++;
return height;
}
const size_type base_size() const { return 1 << height_; }
void meld(size_type index) {
data[index] = Monoid::operation(data[index << 1 ^ 0], data[index << 1 ^ 1]);
}
public:
segment_tree() = default;
segment_tree(segment_tree&&) = default;
segment_tree(const segment_tree&) = default;
segment_tree(size_type size)
: size_(size) {
height_ = get_height(size);
data.assign(base_size() << 1, T{});
}
T fold(size_type left, size_type right) {
T l_value = T{};
T r_value = T{};
for(left += base_size(), right += base_size();
left < right;
left >>= 1, right >>= 1) {
if(left & 1) l_value = Monoid::operation(l_value, data[left++]);
if(right & 1) r_value = Monoid::operation(data[--right], r_value);
}
return Monoid::operation(std::move(l_value), std::move(r_value));
}
void update(size_type index, const updator& update) {
index += base_size();
data[index] = update(data[index]);
while(index >>= 1) meld(index);
}
void update(size_type index, const T& value) { update(index, [&value](const T& x) { return Monoid::operation(x, value); }); }
void change(size_type index, const T& value) { update(index, [&value](const T& x) { return value; }); }
const size_type search(size_type left, const checker& check) {
T val = T{};
size_type k = left + base_size();
while(true) {
if(check(Monoid::operation(val, data[k]))) {
val = Monoid::operation(val, data[k]);
if(k & 1) {
if((k + 1) & k) k = (k + 1) >> 1;
else return size();
} else {
k = k + 1;
}
} else {
if(k < base_size()) {
k = k << 1 ^ 0;
} else {
return k - base_size();
}
}
}
}
const T operator[](size_type index) const { return data[index + base_size()]; }
const size_type size() const { return size_; }
const bool empty() const { return data.empty(); }
};
template<class T>
struct monoid {
using value_type = T;
static value_type operation(const value_type& a, const value_type& b) { return a + b; };
};
// @docs docs/segment_tree.md
#endif
struct node {
int x, id;
node(int x = -(1 << 30), int id = -1): x(x), id(id) {};
node operator+(const node& r) const {
if(x < r.x) return r;
return (*this);
}
};
int main() {
int n; scanf("%d", &n);
std::vector<int> a(n), b(n), c(n);
for(int i = 0; i < n; i++) {
int x; scanf("%d%d%d", &a[i], &c[i], &x);
b[i] = c[i] - x;
}
std::vector<std::pair<int, int>> vec;
for(int i = 0; i < n; i++) vec.push_back({a[i], i});
sort(begin(vec), end(vec));
sort(begin(a), end(a));
segment_tree<monoid<node>> seg(n);
for(int i = 0; i < n; i++) seg.change(i, node(b[vec[i].second], i));
std::vector<int> x(n), y(n), h(n);
std::vector<std::vector<int>> g(n), G(n);
for(int i = 0; i < n; i++) {
int k = upper_bound(begin(a), end(a), b[vec[i].second]) - begin(a);
if(i < k) {
auto p = seg.fold(0, i) + seg.fold(i + 1, k);
x[i] = i;
y[i] = p.id;
} else {
auto p = seg.fold(0, k);
x[i] = i;
y[i] = p.id;
}
if(y[i] == -1) continue;
g[x[i]].push_back(i);
G[y[i]].push_back(i);
h[i]++;
}
std::vector<i64> dp(n, -1);
std::queue<int> qu;
for(int i = 0; i < n; i++) {
if(y[i] != -1) continue;
qu.push(i);
dp[i] = c[vec[i].second];
}
while(!qu.empty()) {
auto v = qu.front(); qu.pop();
for(auto id: G[v]) {
int to = x[id] ^ y[id] ^ v;
if(--h[to]) continue;
dp[to] = std::max(dp[to], dp[v] + (i64)c[vec[to].second]);
qu.push(to);
}
}
std::vector<int> ans(n);
for(int i = 0; i < n; i++) ans[vec[i].second] = dp[i];
for(auto v: ans) {
if(v == -1) printf("BAN\n");
else printf("%lld\n", v);
}
return 0;
}