結果
| 問題 |
No.1641 Tree Xor Query
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-08-07 12:40:17 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 381 ms / 5,000 ms |
| コード長 | 3,230 bytes |
| コンパイル時間 | 2,052 ms |
| コンパイル使用メモリ | 177,500 KB |
| 実行使用メモリ | 26,076 KB |
| 最終ジャッジ日時 | 2024-09-17 19:55:49 |
| 合計ジャッジ時間 | 4,835 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 18 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for (int i = 0; i < (n); ++i)
template<class T> inline bool chmin(T& a, T b) {if (a > b) {a = b;return true;}return false;}
template<class T> inline bool chmax(T& a, T b) {if (a < b) {a = b;return true;}return false;}
using ll = long long;
using P = pair<int,int>;
using Pl = pair<long long,long long>;
using veci = vector<int>;
using vecl = vector<long long>;
using vecveci = vector<vector<int>>;
using vecvecl = vector<vector<long long>>;
const int MOD = 1000000007;
const double pi = acos(-1);
ll gcd(ll a, ll b) {if(b == 0) return a; else return gcd(b,a%b);}
ll lcm(ll a, ll b) {return a*b/gcd(a,b);}
template<typename T>
struct SegTree {
using Fx = function<T(T,T)>; //セグメント木に載せる関数
int n;//葉の数
const T e; //単位元
Fx f;
vector<T> val; //二分木の配列
SegTree(int siz, Fx F, T E) : n(),f(F),e(E),val(siz*4,e) {
int x = 1;
while(siz > x) x *= 2;
n = x;
}
//位置iの要素をxにする
void set(int i, T x) {
i += n-1;
val[i] = x;
while(i > 0) {
i = (i-1)/2;
val[i] = f(val[2*i+1],val[2*i+2]);
}
}
//位置iの要素をF(val[i],x)に置き換える
void update(int i, T x, Fx F) {
i += n-1;
val[i] = F(val[i],x);
while(i>0) i=(i-1)/2,val[i] = f(val[i*2+1],val[i*2+2]);
}
//[a,b)の要素にfを適用する
T query(int a, int b) {return query_sub(a,b,0,0,n);}
T query_sub(int a,int b,int k,int l,int r) {
if(r <= a || b <= l) return e;
else if(a <= l && r <= b) return val[k];
else {
T v1 = query_sub(a,b,2*k+1,l,(l+r)/2);
T v2 = query_sub(a,b,2*k+2,(l+r)/2,r);
return f(v1,v2);
}
}
};
veci C(100010),seen(100010),l1(100010,-1),l2(100010,-1),l3(100010,-1),cnt(100010);
vecveci G(100010);
veci idx,res;
void dfs(int i) {
seen[i] = 1;
res.push_back(C[i]);
idx.push_back(i);
res.push_back(C[i]);
idx.push_back(i);
for(int ni : G[i]) {
if(seen[ni]) continue;
dfs(ni);
}
res.push_back(C[i]);
idx.push_back(i);
}
int main() {
int N,Q; cin >> N >> Q;
REP(i,N) cin >> C[i];
REP(i,N-1) {
int a,b; cin >> a >> b;a--,b--;
G[a].push_back(b);
G[b].push_back(a);
}
dfs(0);
// REP(i,3*N) cout << idx[i] << " ";
// cout << endl;
// REP(i,3*N) cout << res[i] << " ";
// cout << endl;
REP(i,3*N) {
int x = idx[i];
if(cnt[x] == 0) l1[x] = i;
else if(cnt[x] == 1) l2[x] = i;
else l3[x] = i;
cnt[x]++;
}
auto f = [](int a, int b) -> int{return (a^b);};
int e = 0;
SegTree<int> seg(3*N,f,e);
REP(i,3*N) {
seg.set(i,res[i]);
}
// REP(i,N) cout << seg.query(l1[i],l3[i]+1) << " ";
// cout << endl;
REP(_,Q) {
int t,x,y;
cin >> t >> x >> y;
x--;
if(t == 1) {
seg.update(l1[x],y,f);
seg.update(l2[x],y,f);
seg.update(l3[x],y,f);
} else {
cout << seg.query(l1[x],l3[x]+1) << endl;
}
}
return 0;
}