結果
| 問題 |
No.1641 Tree Xor Query
|
| コンテスト | |
| ユーザー |
milanis48663220
|
| 提出日時 | 2021-08-06 22:50:26 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 3,376 ms / 5,000 ms |
| コード長 | 3,718 bytes |
| コンパイル時間 | 1,740 ms |
| コンパイル使用メモリ | 128,876 KB |
| 最終ジャッジ日時 | 2025-01-23 16:05:26 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 18 |
ソースコード
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <tuple>
#include <cmath>
#include <numeric>
#include <functional>
#include <cassert>
#define debug_value(x) cerr << "line" << __LINE__ << ":<" << __func__ << ">:" << #x << "=" << x << endl;
#define debug(x) cerr << "line" << __LINE__ << ":<" << __func__ << ">:" << x << endl;
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; }
using namespace std;
typedef long long ll;
class Lca{
public:
vector<int> depth;
vector<vector<int>> parent;
vector<vector<int>> G;
int root;
int n;
const int N_LOG_MAX = 25;
bool initialized = false;
Lca(vector<vector<int>> g, int _root){
n = g.size();
G = g;
root = _root;
parent = vector<vector<int>>(N_LOG_MAX, vector<int>(n));
depth = vector<int>(n, 0);
}
void init(){
initialized = true;
dfs(root, -1, 0);
for(int i = 0; i < N_LOG_MAX-1; i++){
for(int v = 0; v < n; v++){
if(parent[i][v] < 0) parent[i+1][v] = -1;
else parent[i+1][v] = parent[i][parent[i][v]];
}
}
}
int lca(int u, int v){
assert(initialized);
if(depth[u] > depth[v]) swap(u, v);
for(int i = 0; i < N_LOG_MAX; i++){
if((depth[v] - depth[u]) >> i & 1){
v = parent[i][v];
}
}
if(u == v) return u;
for(int i = N_LOG_MAX-1; i >= 0; i--){
if(parent[i][u] != parent[i][v]) {
u = parent[i][u];
v = parent[i][v];
}
}
return parent[0][u];
}
int dist(int u, int v){
int l = lca(u, v);
return depth[u]+depth[v]-2*depth[l];
}
private:
void dfs(int v, int p, int d){
parent[0][v] = p;
depth[v] = d;
for(int i = 0; i < G[v].size(); i++){
if(G[v][i] != p) dfs(G[v][i], v, d+1);
}
}
};
int n;
bool used[100000];
vector<vector<int>> g;
int c[100000];
int ans[100000];
void clear(){
for(int i = 0; i < n; i++) used[i] = false;
}
void dfs(int v){
used[v] = true;
ans[v] = c[v];
for(int to: g[v]){
if(!used[to]){
dfs(to);
ans[v] ^= ans[to];
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(10) << fixed;
int q; cin >> n >> q;
g.resize(n);
for(int i = 0; i < n; i++) cin >> c[i];
for(int i = 0; i < n-1; i++){
int a, b; cin >> a >> b; a--; b--;
g[a].push_back(b);
g[b].push_back(a);
}
Lca lca(g, 0);
lca.init();
int sq = 300;
auto is_child = [&](int u, int v){
if(lca.depth[u] > lca.depth[v]) return false;
return lca.dist(u, v) == lca.depth[v] - lca.depth[u];
};
vector<int> t(q), x(q), y(q);
int pre = 0;
for(int i = 0; i < q; i++){
if(i%sq == 0){
pre = i;
dfs(0);
clear();
}
cin >> t[i] >> x[i] >> y[i]; x[i]--;
if(t[i] == 1){
c[x[i]] ^= y[i];
}else{
int a = ans[x[i]];
for(int j = pre; j < i; j++){
if(is_child(x[i], x[j])) a ^= y[j];
}
cout << a << endl;
}
}
}
milanis48663220