結果
| 問題 |
No.1641 Tree Xor Query
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-08-06 21:25:14 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 81 ms / 5,000 ms |
| コード長 | 3,876 bytes |
| コンパイル時間 | 2,127 ms |
| コンパイル使用メモリ | 203,176 KB |
| 最終ジャッジ日時 | 2025-01-23 14:31:13 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 18 |
ソースコード
#include <bits/stdc++.h>
using ll = long long;
using std::cin;
using std::cout;
using std::endl;
std::mt19937 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
const int inf = (int)1e9 + 7;
const long long INF = 1LL << 60;
namespace KKT89
{
template<typename Monoid, typename F>
struct SegmentTree {
int sz;
std::vector<Monoid> seg;
const F f;
const Monoid IE;
SegmentTree(int n, const F f, const Monoid& IE) :f(f), IE(IE) {
sz = 1;
while (sz < n) sz *= 2;
seg.assign(2 * sz, IE);
}
void set(int k, const Monoid& x) {
seg[k + sz] = x;
}
void build() {
for (int k = sz - 1; k > 0; k--) {
seg[k] = f(seg[k * 2], seg[k * 2 + 1]);
}
}
void update(int k, const Monoid& x) {
k += sz;
seg[k] = x;
while (k /= 2) {
seg[k] = f(seg[k * 2], seg[k * 2 + 1]);
}
}
Monoid query(int a, int b) {
if (a >= b) return IE;
Monoid L = IE, R = IE;
for (a += sz, b += sz; a < b; a /= 2, b /= 2) {
if (a & 1) L = f(L, seg[a++]);
if (b & 1) R = f(seg[--b], R);
}
return f(L, R);
}
template<typename C>
int find_subtree(int idx, const C& check, Monoid& M, bool type) {
while (idx < sz) {
Monoid nxt = type ? f(seg[2 * idx + 1], M) : f(M, seg[2 * idx]);
if (check(nxt)) idx = idx * 2 + type;
else M = nxt, idx = idx * 2 + 1 - type;
}
return idx - sz;
}
template<typename C>
int min_left(int a, const C& check) {
Monoid L = IE;
if (a <= 0) {
if (check(f(L, seg[1]))) return find_subtree(1, check, L, false);
return -1;
}
int b = sz;
for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
if (a & 1) {
Monoid nxt = f(L, seg[a]);
if (check(nxt)) return find_subtree(a, check, L, false);
L = nxt;
a += 1;
}
}
return -1;
}
template<typename C>
int max_right(int b, const C& check) {
Monoid R = IE;
if (b >= sz) {
if (check(f(seg[1], R))) return find_subtree(1, check, R, true);
return -1;
}
int a = 0;
for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
if (b & 1) {
b -= 1;
Monoid nxt = f(seg[b], R);
if (check(nxt)) return find_subtree(b, check, R, true);
R = nxt;
}
}
return -1;
}
};
}
void solve()
{
int n, kkt; cin >> n >> kkt;
std::vector<ll> c(n);
for (int i = 0; i < n; ++i)
{
cin >> c[i];
}
std::vector<std::vector<int>> g(n);
for (int i = 0; i < n - 1; ++i)
{
int u, v; cin >> u >> v;
u -= 1, v -= 1;
g[u].emplace_back(v);
g[v].emplace_back(u);
}
std::vector<int> in(n), out(n);
{
int idx = 0;
auto dfs = [&](auto &&self, int cur, int pre)->void
{
in[cur] = idx++;
for (const auto &nxt : g[cur])
{
if(nxt == pre)
continue;
self(self, nxt, cur);
}
out[cur] = idx;
};
dfs(dfs, 0, -1);
}
auto f = [&](ll a, ll b)
{
return a ^ b;
};
auto seg = KKT89::SegmentTree(n, f, 0);
for (int i = 0; i < n; ++i)
{
seg.set(in[i], c[i]);
}
seg.build();
while(kkt--)
{
int t, x, y;
cin >> t >> x >> y;
x -= 1;
if(t == 1)
{
ll t = seg.query(in[x], in[x] + 1);
seg.update(in[x], t ^ y);
}
else
{
cout << seg.query(in[x], out[x]) << "\n";
}
}
}
int main()
{
std::cin.tie(nullptr);
std::ios::sync_with_stdio(false);
int kkt = 1;
// cin >> kkt;
while(kkt--)
solve();
return 0;
}