結果
問題 | No.900 aδδitivee |
ユーザー |
![]() |
提出日時 | 2019-10-04 21:52:28 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 337 ms / 2,000 ms |
コード長 | 11,655 bytes |
コンパイル時間 | 1,046 ms |
コンパイル使用メモリ | 84,160 KB |
実行使用メモリ | 29,360 KB |
最終ジャッジ日時 | 2024-10-03 07:30:15 |
合計ジャッジ時間 | 10,151 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 27 |
ソースコード
//#define NDEBUG#include <cstddef>#include <cstdint>#include <iostream>#include <iterator>#include <vector>namespace n91 {using i8 = std::int_fast8_t;using i32 = std::int_fast32_t;using i64 = std::int_fast64_t;using u8 = std::uint_fast8_t;using u32 = std::uint_fast32_t;using u64 = std::uint_fast64_t;using isize = std::ptrdiff_t;using usize = std::size_t;constexpr usize operator"" _z(unsigned long long x) noexcept {return static_cast<usize>(x);}template <class T> class integral_iterator {public:using difference_type = T;using value_type = T;using pointer = const value_type*;using reference = value_type;using iterator_category = std::random_access_iterator_tag;private:using self_type = integral_iterator<value_type>;value_type i;public:constexpr integral_iterator() noexcept : i() {}explicit constexpr integral_iterator(const value_type i) noexcept : i(i) {}constexpr self_type operator++(int) noexcept { return self_type(i++); }constexpr self_type operator--(int) noexcept { return self_type(i--); }constexpr self_type operator[](const difference_type rhs) const noexcept {return self_type(i + rhs);}constexpr self_type& operator++() noexcept {++i;return *this;}constexpr self_type& operator--() noexcept {--i;return *this;}constexpr reference operator*() const noexcept { return i; }constexpr self_type operator+(const difference_type rhs) const noexcept {return self_type(i + rhs);}constexpr self_type operator-(const difference_type rhs) const noexcept {return self_type(i - rhs);}constexpr difference_type operator-(const self_type rhs) const noexcept {return i - rhs.i;}constexpr bool operator<(const self_type rhs) const noexcept {return i < rhs.i;}constexpr bool operator<=(const self_type rhs) const noexcept {return i <= rhs.i;}constexpr bool operator>(const self_type rhs) const noexcept {return i > rhs.i;}constexpr bool operator>=(const self_type rhs) const noexcept {return i >= rhs.i;}constexpr bool operator==(const self_type rhs) const noexcept {return i == rhs.i;}constexpr bool operator!=(const self_type rhs) const noexcept {return i != rhs.i;}constexpr self_type& operator+=(const difference_type rhs) noexcept {i += rhs;return *this;}constexpr self_type& operator-=(const difference_type rhs) noexcept {i -= rhs;return *this;}};template <class T>constexpr integral_iterator<T> make_int_itr(const T i) noexcept {return integral_iterator<T>(i);}class rep {const usize f, l;public:constexpr rep(const usize f, const usize l) noexcept : f(f), l(l) {}constexpr auto begin() const noexcept { return make_int_itr(f); }constexpr auto end() const noexcept { return make_int_itr(l); }};class revrep {const usize f, l;public:revrep(const usize f, const usize l) noexcept : f(l), l(f) {}auto begin() const noexcept {return std::make_reverse_iterator(make_int_itr(f));}auto end() const noexcept {return std::make_reverse_iterator(make_int_itr(l));}};template <class T> auto md_vec(const usize n, const T& value) {return std::vector<T>(n, value);}template <class... Args> auto md_vec(const usize n, Args... args) {return std::vector<decltype(md_vec(args...))>(n, md_vec(args...));}template <class T> constexpr T difference(const T& a, const T& b) {return a < b ? b - a : a - b;}template <class T> T scan() {T ret;std::cin >> ret;return ret;}} // namespace n91#include <cassert>#include <iterator>#include <stdexcept>#include <utility>template <class ValueMonoid, class OperatorMonoid, class Modifier,template <class> class Container>class lazy_segment_tree {public:using value_structure = ValueMonoid;using value_type = typename value_structure::value_type;using const_reference = const value_type &;using operator_structure = OperatorMonoid;using operator_type = typename operator_structure::value_type;using modifier = Modifier;using container_type = Container<::std::pair<value_type, operator_type>>;using size_type = typename container_type::size_type;private:size_type size_, height;container_type tree;static size_type getheight(const size_type size) noexcept {size_type ret = 0;while (static_cast<size_type>(1) << ret < size)++ret;return ret;}static value_type reflect(typename container_type::const_reference element) {return modifier::operation(element.first, element.second);}void recalc(const size_type index) {tree[index].first = value_structure::operation(reflect(tree[index << 1]), reflect(tree[index << 1 | 1]));}static void assign(operator_type& element, const operator_type& data) {element = operator_structure::operation(element, data);}void push(const size_type index) {assign(tree[index << 1].second, tree[index].second);assign(tree[index << 1 | 1].second, tree[index].second);tree[index].second = operator_structure::identity();}void propagate(const size_type index) {for (size_type i = height; i; --i)push(index >> i);}void thrust(const size_type index) {tree[index].first = reflect(tree[index]);push(index);}void evaluate(const size_type index) {for (size_type i = height; i; --i)thrust(index >> i);}void build(size_type index) {while (index >>= 1)recalc(index);}size_type base_size() const { return static_cast<size_type>(1) << height; }public:lazy_segment_tree() : size_(0), height(0), tree() {}explicit lazy_segment_tree(const size_type size): size_(size), height(getheight(size_)),tree(static_cast<size_type>(1) << (height + 1),{ value_structure::identity(), operator_structure::identity() }) {}template <class InputIterator>explicit lazy_segment_tree(InputIterator first, InputIterator last): size_(::std::distance(first, last)), height(getheight(size_)), tree() {const size_type cap = static_cast<size_type>(1) << height;tree.reserve(cap << 1);tree.resize(cap,{ value_structure::identity(), operator_structure::identity() });for (; first != last; ++first)tree.emplace_back(*first, operator_structure::identity());tree.resize(cap << 1,{ value_structure::identity(), operator_structure::identity() });for (size_type i = cap - 1; i; --i)recalc(i);}bool empty() const { return !size_; }size_type size() const { return size_; }const_reference operator[](size_type index) {assert(index < size());index += base_size();evaluate(index);tree[index].first = reflect(tree[index]);tree[index].second = operator_structure::identity();return tree[index].first;}const_reference at(size_type index) {if (index < size()) {throw ::std::out_of_range("index out of range");}else {index += base_size();evaluate(index);tree[index].first = reflect(tree[index]);tree[index].second = operator_structure::identity();return tree[index].first;}}value_type fold(size_type first, size_type last) {assert(first <= last);assert(first <= size());assert(last <= size());first += base_size();last += base_size();evaluate(first);evaluate(last - 1);value_type ret_l = value_structure::identity(),ret_r = value_structure::identity();for (; first < last; first >>= 1, last >>= 1) {if (first & 1)ret_l = value_structure::operation(ret_l, reflect(tree[first++]));if (last & 1)ret_r = value_structure::operation(reflect(tree[last - 1]), ret_r);}return value_structure::operation(ret_l, ret_r);}template <class F> size_type search(const F& f) {if (f(value_structure::identity()))return static_cast<size_type>(0);if (!f(reflect(tree[1])))return size() + 1;value_type acc = value_structure::identity();size_type i = 1;while (i < base_size()) {thrust(i);if (!f(value_structure::operation(acc, reflect(tree[i <<= 1]))))acc = value_structure::operation(acc, reflect(tree[i++]));}return i - base_size() + 1;}template <class F> void update(size_type index, const F& f) {assert(index < size());index += base_size();propagate(index);tree[index].first = f(reflect(tree[index]));tree[index].second = operator_structure::identity();build(index);}void update(size_type first, size_type last, const operator_type& data) {assert(first <= last);assert(first <= size());assert(last <= size());first += base_size();last += base_size();propagate(first);propagate(last - 1);for (size_type left = first, right = last; left < right;left >>= 1, right >>= 1) {if (left & 1)assign(tree[left++].second, data);if (right & 1)assign(tree[right - 1].second, data);}build(first);build(last - 1);}};template <class T> class plus_monoid {public:using value_type = T;static value_type operation(const value_type& x, const value_type& y) {return x + y;}static value_type identity() { return value_type(0); }static value_type reverse(const value_type& x) { return x; }};#include <algorithm>#include <iostream>#include <utility>namespace n91 {using pair = std::pair<u64, u64>;struct val {using value_type = pair;static value_type operation(const value_type& x, const value_type& y) {return { x.first + y.first, x.second + y.second };}static value_type identity() {return { static_cast<u64>(0), static_cast<u64>(0) };}};struct modify {static pair operation(const pair& x, const u64 y) {return { x.first + y * x.second, x.second };}};template<class T>using vec_alias=std::vector<T>;void main_() {const usize n = scan<usize>();struct edge {usize to;u64 w;};auto g = md_vec(n, 0_z, edge());for (const auto i : rep(0_z, n - 1_z)) {const usize u = scan<usize>();const usize v = scan<usize>();const u64 w = scan<u64>();g[u].push_back({ v, w });g[v].push_back({ u, w });}std::vector<usize> in(n), out(n);lazy_segment_tree<val, plus_monoid<u64>, modify, vec_alias> lsg((n - 1_z) * 2_z);{usize cnt = 0_z;const auto dfs = [&](const auto& dfs, const usize v, const usize p)->void {in[v] = cnt;for (const auto& e : g[v]) {if (e.to != p) {lsg.update(cnt, [&](auto) { return pair(e.w, u64(1)); });++cnt;dfs(dfs, e.to, v);lsg.update(cnt, [&](auto) { return pair(-e.w, -u64(1)); });++cnt;}}out[v] = cnt;};dfs(dfs, 0_z, n);}const usize q = scan<usize>();for (const auto i : rep(0_z, q)) {const usize t = scan<usize>();if (t == 1_z) {const usize a = scan<usize>();const u64 x = scan<u64>();lsg.update(in[a], out[a], x);}else {const usize b = scan<usize>();std::cout << lsg.fold(0_z, in[b]).first << std::endl;}}}} // namespace n91int main() {n91::main_();return 0;}