#include<bits/stdc++.h>
#define ll long long
#define int ll
#define pii pair<int,int>
#define p3i pair<int,pii>
#define p4i pair<pii,pii>
#define fi first
#define se second
using namespace std;
const int maxn = 2e5 + 2;
int h[maxn],ans[maxn];
vector<p3i> a[maxn];
vector<p4i> qr[maxn];
struct node {
int u,pa,jump,len,vpa,vjump;
node() {};
node(int u) : u(u) {}
node(int u, int pa, int jump, int len, int vpa,int vjump) : u(u), pa(pa), jump(jump), len(len), vpa(vpa), vjump(vjump) {}
};
node info[maxn];
void add(int u,int pa,int w) {
h[u] = h[pa] + 1;
int len,jump,vpa = w,vjump;
if (info[pa].len == info[info[pa].jump].len) {
len = info[pa].len * 2 + 1;
jump = info[info[pa].jump].jump;
vjump = w ^ info[pa].vjump ^ info[info[pa].jump].vjump;
}
else {
len = 1;
jump = pa;
vjump = w;
}
info[u] = node(u,pa,jump,len,vpa,vjump);
// cerr << "ADD:" << u << " pa: " << pa << " jump: " << jump << " len: " << len << " and: " << vpa << " " << vjump << endl;
}
pii binlift(int u, int k) {
int des = h[u] - k;
int value = 0;
// cerr << "lift " << u << " " << h[u] << " " << h[u] - k << endl;
while (h[u] != des) {
if (h[info[u].jump] > k) {
value ^= info[u].vpa;
u = info[u].pa;
}
else {
value ^= info[u].vjump;
u = info[u].jump;
}
}
// cerr << "return: " << u << " " << value << endl;
return {u,value};
}
int LCA(int u, int v) {
if (h[u] > h[v]) swap(u,v);
pii tmp = binlift(v,h[v]-h[u]);
int val = 0;
v = tmp.first;
// cerr << u << " " << v << endl;
while (u != v) {
if (info[u].jump != info[v].jump) {
val ^= info[u].vjump ^ info[v].vjump;
// cerr << val << " | " << u << " " << v << " : " << info[u].vjump << " " << info[v].vjump << " : " << (info[u].vjump ^ info[v].vjump) << endl;
u = info[u].jump;
v = info[v].jump;
}
else {
val ^= info[u].vpa ^ info[v].vpa;
// cerr << val << " | " << u << " " << v << " : " << info[u].vpa << " " << info[v].vpa << " : " << (info[u].vpa ^ info[v].vpa) << endl;
u = info[u].pa;
v = info[v].pa;
}
}
// cerr << val << " " << tmp.second << endl;
return val ^ tmp.second;
}
struct nodetrie {
int la, t[2];
nodetrie *p[2];
nodetrie() {
t[0] = t[1] = 0;
p[0] = p[1] = nullptr;
la = 0;
}
nodetrie(nodetrie *l, nodetrie *r, int tl, int tr) {
t[0] = (tl);
t[1] = (tr);
p[0] = (l);
p[1] = (r);
la = 0;
}
};
void push(nodetrie *p,int pos) {
if (p->la) {
for (int i = 0; i < 2; i++) {
if (p->p[i]!=nullptr) p->p[i]->la ^= p->la;
}
if (p->la & (1<<pos-1)) {
swap(p->p[0],p->p[1]), swap(p->t[0],p->t[1]);
}
p->la=0;
}
}
class trie {
public:
int sz;
nodetrie *root = new nodetrie();
void update(nodetrie *p, int pos, int val, int t) {
// cerr << "update: "<< pos << endl;
if (pos==0) return;
push(p,pos);
int bit = (val&(1<<pos-1))!=0;
if (p->p[bit]==nullptr){
p->t[bit] = t;
p->p[bit] = new nodetrie();
}
else {
p->t[bit] = min(t,p->t[bit]);
}
update( p->p[bit], pos - 1, val, t);
}
int get(nodetrie *p, int pos, int val, int t) {
if (pos==0) return 0;
// cerr<< pos << " " << t << endl;
assert(p!=nullptr);
push(p,pos);
int bit = (val&(1<<pos-1))!=0;
// cerr<< pos << " " << t << " " << bit << endl;
if (p->p[bit]==nullptr || p->t[bit] > t){
// cerr << "Ok" << endl;
return get(p->p[!bit],pos-1,val,t) | (!bit << pos-1);
}
else {
// cerr << "xam" << endl;
return get(p->p[bit],pos-1,val,t) | (bit << pos-1);
}
}
int get(int val, int t) {
return get(root,31,val,t);
}
void update(int val, int t) {
update(root,31,val,t);
sz++;
}
void addlazy(int val) {
root->la ^= val;
}
void init(int t) {
// cerr << "init: " << t << endl;
update(root,31,0,t);
sz = 0;
}
void print(nodetrie *p, int pos, int val, int t) {
// if (pos <= 5) cerr << "> " << pos << " " << (p->la) << " | " << p->la << endl;
push(p,pos);
if (pos==0) {
cerr << ">> " << val << " "<< t<< endl; return;
}
for (int i = 0; i < 2; i++) {
if (p->p[i] == nullptr) continue;
print(p->p[i], pos-1, val | (i<<pos-1), max(t,p->t[i]));
}
}
void print(int u) {
cerr << "tree print: " << u << endl;
print(root,31,0,0);
}
};
void merged(nodetrie *a, nodetrie *b, int pos) {
if (pos==0) return;
push(a,pos);
push(b,pos);
// cerr << "merge: " << pos << endl;
for (int i = 0; i < 2; i++) {
if (b->p[i] == nullptr) continue;
if (a->p[i] == nullptr) {
a->p[i] = new nodetrie();
a->t[i] = b->t[i];
}
else {
a->t[i] = min(a->t[i], b->t[i]);
}
merged(a->p[i], b->p[i], pos - 1);
}
}
trie tree[maxn];
void dfs(int u) {
// cerr <<"vst u:" << u << endl;
if (a[u].empty()) {
// tree[u].print(u);
for (p4i val : qr[u]) {
int x,y,idx,t; tie(x,y) = val.fi; tie(idx,t) = val.se;
int ori = LCA(x,y);
ans[idx] = tree[u].get(~ori,t);
}
return;
}
for (p3i tmp : a[u]) {
int w,v;
w = tmp.se.fi;
v = tmp.fi;
tree[v].init(tmp.se.se);
dfs(v);
tree[v].addlazy(w);
if (tree[u].sz < tree[v].sz) swap(tree[u], tree[v]);
merged(tree[u].root, tree[v].root, 31);
}
// tree[u].print(u);
for (p4i val : qr[u]) {
int x,y,idx,t; tie(x,y) = val.fi; tie(idx,t) = val.se;
int ori = LCA(x,y);
// cerr << ori << " : " << t << endl;
ans[idx] = ori ^ tree[u].get(~ori,t);
}
}
void solve() {
int q; cin >> q;
int cnt = 1, cntqr=0, t = 0;
info[1] = node(1,0,0,-1,0,0);
for (int i = 1; i <= q; i++) {
string s;cin >> s;
t++;
if (s=="Add") {
int x,w; cin >> x >> w;
add(++cnt,x,w);
a[x].push_back({cnt,{w,t}});
}
else {
int x,y; cin >> x >> y;
qr[y].push_back({{x,y},{++cntqr,t}});
}
}
tree[1].init(0);
dfs(1);
for (int i = 1; i <= cntqr; i++) {
cout << ans[i] << '\n';
}
}
signed main() {
cin.tie(0) -> sync_with_stdio(0);
solve();
return 0;
}
Compilation message
klasika.cpp: In function 'void push(nodetrie*, long long int)':
klasika.cpp:108:28: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
108 | if (p->la & (1<<pos-1)) {
| ~~~^~
klasika.cpp: In member function 'void trie::update(nodetrie*, long long int, long long int, long long int)':
klasika.cpp:123:31: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
123 | int bit = (val&(1<<pos-1))!=0;
| ~~~^~
klasika.cpp: In member function 'long long int trie::get(nodetrie*, long long int, long long int, long long int)':
klasika.cpp:139:31: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
139 | int bit = (val&(1<<pos-1))!=0;
| ~~~^~
klasika.cpp:143:62: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
143 | return get(p->p[!bit],pos-1,val,t) | (!bit << pos-1);
| ~~~^~
klasika.cpp:147:60: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
147 | return get(p->p[bit],pos-1,val,t) | (bit << pos-1);
| ~~~^~
klasika.cpp: In member function 'void trie::print(nodetrie*, long long int, long long int, long long int)':
klasika.cpp:178:48: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
178 | print(p->p[i], pos-1, val | (i<<pos-1), max(t,p->t[i]));
| ~~~^~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5057 ms |
24400 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5057 ms |
24400 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
711 ms |
524288 KB |
Execution killed with signal 9 |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
5057 ms |
24400 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |