結果
| 問題 |
No.1030 だんしんぐぱーりない
|
| コンテスト | |
| ユーザー |
KoD
|
| 提出日時 | 2020-04-17 22:51:38 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 7,692 bytes |
| コンパイル時間 | 2,018 ms |
| コンパイル使用メモリ | 92,492 KB |
| 最終ジャッジ日時 | 2025-01-09 20:31:24 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 26 WA * 1 RE * 7 TLE * 6 |
ソースコード
#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#include <numeric>
template <class T, class U>
inline bool chmin(T &lhs, const U &rhs) {
if (lhs > rhs) {
lhs = rhs;
return true;
}
return false;
}
template <class T, class U>
inline bool chmax(T &lhs, const U &rhs) {
if (lhs < rhs) {
lhs = rhs;
return true;
}
return false;
}
// [l, r) from l to r
struct range {
struct itr {
int i;
constexpr itr(int i_): i(i_) { }
constexpr void operator ++ () { ++i; }
constexpr int operator * () const { return i; }
constexpr bool operator != (itr x) const { return i != x.i; }
};
const itr l, r;
constexpr range(int l_, int r_): l(l_), r(std::max(l_, r_)) { }
constexpr itr begin() const { return l; }
constexpr itr end() const { return r; }
};
// [l, r) from r to l
struct revrange {
struct itr {
int i;
constexpr itr(int i_): i(i_) { }
constexpr void operator ++ () { --i; }
constexpr int operator * () const { return i; }
constexpr bool operator != (itr x) const { return i != x.i; }
};
const itr l, r;
constexpr revrange(int l_, int r_): l(l_ - 1), r(std::max(l_, r_) - 1) { }
constexpr itr begin() const { return r; }
constexpr itr end() const { return l; }
};
class heavy_light_decomposition {
private:
std::vector<std::vector<int>> graph;
std::vector<int> size, parent, head;
int index;
void calc_size(int u, int p) {
size[u] = 1;
for (int v: graph[u]) {
if (v != p) {
calc_size(v, u);
size[u] += size[v];
}
}
}
void decompose(int u, int p, int h) {
label[u] = index;
head[u] = h;
parent[u] = p;
++index;
int max = -1, heavy = -1;
for (int v : graph[u]) {
if (v != p) {
if (max < size[v]) {
max = size[v];
heavy = v;
}
}
}
if (heavy == -1) {
return;
}
decompose(heavy, u, h);
for (int v : graph[u]) {
if (v != p && v != heavy) {
decompose(v, u, v);
}
}
}
public:
std::vector<int> label;
heavy_light_decomposition() { }
heavy_light_decomposition(int size_) { init(size_); }
void init(int size_) {
graph.assign(size_, { });
size.assign(size_, 0);
parent.assign(size_, 0);
head.assign(size_, 0);
label.assign(size_, 0);
}
void add_edge(int u, int v) {
graph[u].push_back(v);
graph[v].push_back(u);
}
void build() {
index = 0;
calc_size(0, -1);
decompose(0, -1, 0);
}
template <class T>
void each_edge(int u, int v, const T &func) const {
while (true) {
if (label[u] > label[v]) {
std::swap(u, v);
}
if (head[u] == head[v]) {
if (label[u] + 1 <= label[v]) {
func(label[u] + 1, label[v]);
}
return;
}
func(label[head[v]], label[v]);
v = parent[head[v]];
}
}
template <class T>
void each_vertex(int u, int v, const T &func) const {
while (true) {
if (label[u] > label[v]) {
std::swap(u, v);
}
if (head[u] == head[v]) {
func(label[u], label[v]);
return;
}
func(label[head[v]], label[v]);
v = parent[head[v]];
}
}
int lca(int u, int v) const {
if (label[u] > label[v]) {
std::swap(u, v);
}
while (label[u] <= label[v]) {
if (head[u] == head[v]) {
return u;
}
v = parent[head[v]];
}
return v;
}
};
heavy_light_decomposition hld;
template <class T>
class segment_tree {
public:
using value_type = typename T::value_type;
using effector_type = typename T::effector_type;
using value_operation = typename T::value_operation;
using merge_operation = typename T::merge_operation;
private:
int size;
const value_operation op1;
const merge_operation op2;
std::vector<value_type> node;
void update() {
for (int k = size - 1; k > 0; --k) {
node[k] = op1(node[k << 1 | 0], node[k << 1 | 1]);
}
}
public:
segment_tree(): op1(value_operation()), op2(merge_operation()) { }
segment_tree(int size_, const value_type &initial_ = value_operation().identity):
op1(value_operation()), op2(merge_operation())
{ init(size_, initial_); }
segment_tree(const std::vector<value_type> &node_):
op1(value_operation()), op2(merge_operation())
{ build(node_); }
void init(int size_, const value_type &initial_ = value_operation().identity) {
size = 1;
while (size < size_) {
size <<= 1;
}
node.assign(size << 1, initial_);
update();
}
void build(const std::vector<value_type> &node_) {
init(node_.size());
assign(node_.begin(), node_.end(), 0);
}
void modify(int i, const effector_type &x) {
i += size;
node[i] = op2(node[i], x);
while (i > 1) {
i >>= 1;
node[i] = op1(node[i << 1 | 0], node[i << 1 | 1]);
}
}
template <class U>
void modify(U begin, U end, int i) {
i += size;
while (begin != end) {
node[i] = op2(node[i], *begin);
++i;
++begin;
}
update();
}
void assign(int i, const value_type &x) {
i += size;
node[i] = x;
while (i > 1) {
i >>= 1;
node[i] = op1(node[i << 1 | 0], node[i << 1 | 1]);
}
}
template <class U>
void assign(U begin, U end, int i) {
i += size;
while (begin != end) {
node[i] = *begin;
++i;
++begin;
}
update();
}
value_type operator [] (int i) const {
return node[i + size];
}
value_type fold(int l, int r) const {
l += size;
r += size;
value_type resl = op1.identity;
value_type resr = op1.identity;
while (l < r) {
if (l & 1) {
resl = op1(resl, node[l++]);
}
if (r & 1) {
resr = op1(node[--r], resr);
}
l >>= 1;
r >>= 1;
}
return op1(resl, resr);
}
};
template <class T>
struct fix_point: private T {
explicit constexpr fix_point(T &&func): T(std::forward<T>(func)) { }
template <class... Args>
constexpr decltype(auto) operator () (Args &&... args) const {
return T::operator()(*this, std::forward<Args>(args)...);
}
};
int main() {
int N, K, Q;
std::cin >> N >> K >> Q;
std::vector<int> vivace(N);
std::vector<std::vector<int>> graph(N);
for (int &x: vivace) {
std::cin >> x;
}
std::vector<int> lives(K);
for (int &x: lives) {
std::cin >> x;
--x;
}
hld.init(N);
for (int i: range(0, N - 1)) {
int a, b;
std::cin >> a >> b;
--a; --b;
graph[a].push_back(b);
graph[b].push_back(a);
hld.add_edge(a, b);
}
hld.build();
struct monoid {
using value_type = int;
using effector_type = int;
struct value_operation {
value_type identity = -1;
value_type operator () (const value_type &i, const value_type &j) const {
if (i == -1) return j;
if (j == -1) return i;
return hld.lca(i, j);
}
};
struct merge_operation {
value_type operator () (const value_type &i, const effector_type &j) const {
return j;
}
};
};
segment_tree<monoid> seg(N);
for (int i: range(0, K)) {
seg.assign(i, lives[i]);
}
fix_point([&](auto dfs, int u, int p) -> void {
if (p != -1) {
chmax(vivace[u], vivace[p]);
}
for (int v: graph[u]) {
if (v != p) {
dfs(v, u);
}
}
})(0, -1);
while (Q--) {
int type;
std::cin >> type;
if (type == 1) {
int x, y;
std::cin >> x >> y;
--x; --y;
seg.assign(x, y);
}
else {
int l, r;
std::cin >> l >> r;
--l;
std::cout << vivace[seg.fold(l, r)] << '\n';
}
}
return 0;
}
KoD