假設 \(p\) 是左兒子
\(f\) 是 \(p\) 的爸爸
\(c\) 是 \(p\) 的右兒子
\(p\) 的爸爸變 \(f\) 的爸爸
\(f\) 成為 \(p\) 的右兒子
\(c\) 變成 \(f\) 的左兒子
假設 \(p\) 是右兒子
\(f\) 是 \(p\) 的爸爸
\(c\) 是 \(p\) 的左兒子
\(p\) 的爸爸變 \(f\) 的爸爸
\(f\) 成為 \(p\) 的左兒子
\(c\) 變成 \(f\) 的右兒子
#include <bits/stdc++.h>
#define lc C[p][0]
#define rc C[p][1]
using namespace std;
array<int, 100004> S, F;
array<array<int, 2>, 100004> C;
void pull(int p){
S[p] = S[lc] + S[rc] + 1;
}
int get(int p){
return p == C[F[p]][1];
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(F[f]) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
轉 \(f\)
轉 \(p\)
轉 \(p\)
轉 \(p\)
void splay(int p){
for(int f = F[p]; f; turn(p), f = F[p]){
if(F[f]) turn(get(p) == get(f)? f : p);
}
}
相信學過 treap 的大家應該都對這些東西不陌生
然後這4個東西都不會在 LCT 用到
int rank(int p){
splay(p);
return S[lc] + 1;
}
int find(int p, int k){
splay(p);
while(k){
if(k > S[lc] + 1) k -= S[lc] + 1, p = rc;
else if(k <= S[lc]) p = lc;
else return p;
}
return 0;
}
void merge(int u, int v){
if(!S[u] || !S[v] || find(u, 1) == find(v, 1)) return;
u = find(u, S[u]), v = find(v, 1);
splay(u), splay(v);
C[u][1] = v, F[v] = u;
pull(u);
}
void split(int p, int k){
if(!k || !S[p]) return;
p = find(p, k), splay(p);
F[rc] = 0, rc = 0;
pull(p);
}
#include <bits/stdc++.h>
#define lc C[p][0]
#define rc C[p][1]
using namespace std;
array<int, 100004> S, F, rev;
array<array<int, 2>, 100004> C;
void pull(int p){
S[p] = S[lc] + S[rc] + 1;
}
void push(int p){
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
rev[p] = 0;
}
int get(int p){
return p == C[F[p]][1];
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(F[f]) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
void update(int p){
if(F[p]) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; f; turn(p), f = F[p]){
if(F[f]) turn(get(p) == get(f)? f : p);
}
}
int rank(int p){
splay(p);
return S[lc] + 1;
}
int find(int p, int k){
splay(p);
while(k){
push(p);
if(k > S[lc] + 1) k -= S[lc] + 1, p = rc;
else if(k <= S[lc]) p = lc;
else return p;
}
return 0;
}
void merge(int u, int v){
if(!S[u] || !S[v] || find(u, 1) == find(v, 1)) return;
u = find(u, S[u]), v = find(v, 1);
splay(u), splay(v);
C[u][1] = v, F[v] = u;
pull(u);
}
void split(int p, int k){
if(!k || !S[p]) return;
p = find(p, k), splay(p);
F[rc] = 0, rc = 0;
pull(p);
}
#include <bits/stdc++.h>
#define lc C[p][0]
#define rc C[p][1]
using namespace std;
array<int, 130004> S, F, rev;
array<array<int, 2>, 130004> C;
void pull(int p){
S[p] = S[lc] + S[rc] + 1;
}
void push(int p){
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
rev[p] = 0;
}
int get(int p){
return p == C[F[p]][1];
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(F[f]) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
void update(int p){
if(F[p]) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; f; turn(p), f = F[p]){
if(F[f]) turn(get(p) == get(f)? f : p);
}
}
int find(int p, int k){
splay(p);
while(k){
push(p);
if(k > S[lc] + 1) k -= S[lc] + 1, p = rc;
else if(k <= S[lc]) p = lc;
else return p;
}
return 0;
}
void merge(int u, int v){
if(!S[u] || !S[v] || find(u, 1) == find(v, 1)) return;
u = find(u, S[u]), v = find(v, 1);
splay(u), splay(v);
C[u][1] = v, F[v] = u;
pull(u);
}
void split(int p, int k){
if(!k || !S[p]) return;
p = find(p, k), splay(p);
F[rc] = 0, rc = 0;
pull(p);
}
void build(int l, int r, int f){
if(l > r) return;
int p = (l + r) >> 1;
F[p] = f, C[f][p > f] = p;
build(l, p - 1, p), build(p + 1, r, p);
pull(p);
}
void print(int p){
if(!p) return;
push(p);
print(lc), cout << p << " ", print(rc);
}
signed main(){
cin.tie(0), cout.tie(0), ios::sync_with_stdio(0);
int n, q, l1, r1, l2, r2, a, b, c, d, e;
string t;
cin >> n >> q;
build(1, n, 0);
C[0][1] = 0;
while(q--){
cin >> t >> l1 >> r1;
if(t == "REV"){
a = find(1, l1 - 1), b = find(1, l1), c = find(1, r1 + 1);
split(b, r1), split(b, l1 - 1);
splay(b), rev[b] ^= 1;
merge(a, b), merge(b, c);
}else{
cin >> l2 >> r2;
a = find(1, l1 - 1), b = find(1, l1), c = find(1, r1 + 1), d = find(1, l2), e = find(1, r2 + 1);
split(b, r2), split(b, l2 - 1), split(b, r1), split(b, l1 - 1);
merge(a, d), merge(d, c), merge(c, b), merge(b, e);
}
}
splay(1), print(1), cout << "\n";
return 0;
}
實 虛
在 splay 中越左邊代表在原樹上越上面
虛邊記父不記子
int kabab(int p){
int c;
for(c = 0; p; c = p, p = F[p]){
splay(p), rc = c, pull(p);
}
return c;
}
void plant(int p){
p = kabab(p);
rev[p] ^= 1;
}
int find(int p){
p = kabab(p);
for(; lc; push(p), p = lc);
return p;
}
void link(int u, int v){
if(find(u) == find(v)) return;
if(u > v) swap(u, v);
E.insert({u, v});
plant(u), splay(u), F[u] = v;
}
void cut(int u, int v){
if(u > v) swap(u, v);
if(E.find({u, v}) == E.end()) return;
E.erase({u, v});
plant(u), kabab(v), splay(u);
F[C[u][1]] = 0, C[u][1] = 0;
pull(u);
}
#include <bits/stdc++.h>
#define lc C[p][0]
#define rc C[p][1]
using namespace std;
array<int, 100004> F, S, rev;
array<array<int, 2>, 100004> C;
set<pair<int, int>> E;
int get(int p){
return p == C[F[p]][1];
}
int root(int p){
return p != C[F[p]][get(p)];
}
void pull(int p){
S[p] = S[lc] + S[rc] + 1;
}
void push(int p){
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
rev[p] = 0;
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(!root(f)) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
void update(int p){
if(!root(p)) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; !root(p); turn(p), f = F[p]){
if(!root(f)) turn(get(p) == get(f)? f : p);
}
}
int kabab(int p){
int c;
for(c = 0; p; c = p, p = F[p]){
splay(p), rc = c, pull(p);
}
return c;
}
void plant(int p){
p = kabab(p);
rev[p] ^= 1;
}
int find(int p){
p = kabab(p);
for(; lc; push(p), p = lc);
splay(p);
return p;
}
void link(int u, int v){
if(find(u) == find(v)) return;
if(u > v) swap(u, v);
E.insert({u, v});
plant(u), splay(u), F[u] = v;
}
void cut(int u, int v){
if(u > v) swap(u, v);
if(E.find({u, v}) == E.end()) return;
E.erase({u, v});
plant(u), kabab(v), splay(u);
F[v] = 0, C[u][1] = 0;
pull(u);
}
扣點中間就會現身了
#include <bits/stdc++.h>
#define lc C[p][0]
#define rc C[p][1]
using namespace std;
array<int, 100004> F, X, V, rev;
array<array<int, 2>, 100004> C;
set<pair<int, int>> E;
int get(int p){
return p == C[F[p]][1];
}
int root(int p){
return p != C[F[p]][get(p)];
}
void pull(int p){
X[p] = X[lc] ^ X[rc] ^ V[p];
}
void push(int p){
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
rev[p] = 0;
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(!root(f)) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
void update(int p){
if(!root(p)) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; !root(p); turn(p), f = F[p]){
if(!root(f)) turn(get(p) == get(f)? f : p);
}
}
int kabab(int p){
int c;
for(c = 0; p; c = p, p = F[p]){
splay(p), rc = c, pull(p);
}
return c;
}
void plant(int p){
p = kabab(p);
rev[p] ^= 1;
}
int find(int p){
p = kabab(p);
for(; lc; push(p), p = lc);
return p;
}
void link(int u, int v){
if(find(u) == find(v)) return;
if(u > v) swap(u, v);
E.insert({u, v});
plant(u), splay(u), F[u] = v;
}
void cut(int u, int v){
if(u > v) swap(u, v);
if(E.find({u, v}) == E.end()) return;
E.erase({u, v});
plant(u), kabab(v), splay(u);
F[C[u][1]] = 0, C[u][1] = 0;
pull(u);
}
signed main(){
int n, q, t, x, y;
cin >> n >> q;
for(int i = 1; i <= n; i++) cin >> V[i], X[i]= V[i];
while(q--){
cin >> t >> x >> y;
if(t == 1) link(x, y);
else if(t == 2) cut(x, y);
else if(t == 3) splay(x), X[x] ^= V[x] ^ y, V[x] = y;
else{
plant(x), kabab(y), splay(x);
cout << X[x] << "\n";
}
}
return 0;
}
#include <bits/stdc++.h>
#define int unsigned
#define lc C[p][0]
#define rc C[p][1]
using namespace std;
const int mod = 51061;
array<int, 100004> F, S, A, M, val, sum, rev;
array<array<int, 2>, 100004> C;
int add(int a, int b){
return (a + b) % mod;
}
int mul(int a, int b){
return a * b % mod;
}
int get(int p){
return p == C[F[p]][1];
}
int root(int p){
return p != C[F[p]][get(p)];
}
void pull(int p){
sum[p] = add(val[p], add(sum[lc], sum[rc]));
S[p] = S[lc] + S[rc] + 1;
}
void push(int p){
sum[lc] = add(mul(sum[lc], M[p]), mul(S[lc], A[p]));
sum[rc] = add(mul(sum[rc], M[p]), mul(S[rc], A[p]));
val[lc] = add(mul(val[lc], M[p]), A[p]);
val[rc] = add(mul(val[rc], M[p]), A[p]);
A[lc] = add(mul(A[lc], M[p]), A[p]);
A[rc] = add(mul(A[rc], M[p]), A[p]);
M[lc] = mul(M[lc], M[p]), M[rc] = mul(M[rc], M[p]);
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
A[p] = 0, M[p] = 1, rev[p] = 0;
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(!root(f)) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
void update(int p){
if(!root(p)) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; !root(p); turn(p), f = F[p]){
if(!root(f)) turn(get(p) == get(f)? f : p);
}
}
int kabab(int p){
int c;
for(c = 0; p; c = p, p = F[p]){
splay(p), rc = c, pull(p);
}
return c;
}
void plant(int p){
p = kabab(p);
rev[p] ^= 1;
}
void link(int u, int v){
plant(u), splay(u), F[u] = v;
}
void cut(int u, int v){
plant(u), kabab(v), splay(u);
F[C[u][1]] = 0, C[u][1] = 0;
pull(u);
}
signed main(){
char op;
int n, q, u, v, c;
cin >> n >> q;
for(int i = 1; i <= n; i++) sum[i] = val[i] = S[i] = M[i] = 1;
for(int i = 1; i < n; i++){
cin >> u >> v;
link(u, v);
}
while(q--){
cin >> op >> u >> v;
if(op == '+'){
cin >> c;
plant(u), kabab(v), splay(u);
sum[u] = add(sum[u], mul(S[u], c));
val[u] = add(val[u], c);
A[u] = add(A[u], c);
}else if(op == '-'){
cut(u, v);
cin >> u >> v;
link(u, v);
}else if(op == '*'){
cin >> c;
plant(u), kabab(v), splay(u);
sum[u] = mul(sum[u], c);
val[u] = mul(val[u], c);
A[u] = mul(A[u], c), M[u] = mul(M[u], c);
}else{
plant(u), kabab(v), splay(u);
cout << sum[u] << "\n";
}
}
return 0;
}
這題他媽的有自環
#include <bits/stdc++.h>
#define lc C[p][0]
#define rc C[p][1]
#define pb push_back
using namespace std;
struct edge{
int p, x;
};
const int inf = 1 << 30;
array<int, 250004> L, R, F, M, V, rev, in;
array<array<int, 2>, 250004> C;
vector<edge> E;
bool cmp(edge a, edge b){
return a.x < b.x;
}
void pull(int p){
M[p] = min({V[p], M[lc], M[rc]});
}
void push(int p){
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
rev[p] = 0;
}
int root(int p){
return p != C[F[p]][0] && p != C[F[p]][1];
}
int get(int p){
return p == C[F[p]][1];
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(!root(f)) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
void update(int p){
if(!root(p)) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; !root(p); turn(p), f = F[p]){
if(!root(f)) turn(get(f) == get(p)? f : p);
}
}
int kabab(int p){
int c = 0;
for(; p; c = p, p = F[p]){
splay(p), rc = c, pull(p);
}
return c;
}
void plant(int p){
p = kabab(p);
rev[p] ^= 1;
}
int find(int p){
p = kabab(p);
for(; lc; push(p), p = lc);
return p;
}
void link(int u, int v){
plant(u), splay(u), F[u] = v;
}
void cut(int u, int v){
plant(u), kabab(v), splay(u);
F[C[u][1]] = 0, C[u][1] = 0, pull(u);
}
int query(int p){
splay(p);
for(; p; push(p), p = M[lc] < M[rc]? lc : rc){
if(V[p] == M[p]) return p;
}
return p;
}
signed main(){
int n, m, u, v, w, q, ans = inf, cnt = 0;
cin >> n >> m;
for(int i = 0; i <= n + m; i++) V[i] = M[i] = inf;
for(int i = 0, k = n + 1; i < m; i++, k++){
cin >> u >> v >> w;
L[k] = u, R[k] = v, V[k] = w;
E.pb({k, w});
}
sort(E.begin(), E.end(), cmp);
for(int lp = 0, rp = 0; rp < m; rp++){
auto [p, x] = E[rp];
if(L[p] == R[p]) continue;
if(find(L[p]) == find(R[p])){
plant(L[p]), kabab(R[p]), q = query(L[p]);
cut(L[q], q), cut(R[q], q), in[q] = 0, cnt--;
}
link(L[p], p), link(p, R[p]), in[p] = 1, cnt++;
while(!in[E[lp].p]) lp++;
if(cnt == n - 1) ans = min(ans, E[rp].x - E[lp].x);
}
cout << ans << "\n";
return 0;
}
#include <bits/stdc++.h>
#define lc C[p][0]
#define rc C[p][1]
#define int long long
using namespace std;
array<int, 100004> F, S, I, rev;
array<array<int, 2>, 100004> C;
void pull(int p){
S[p] = S[lc] + S[rc] + 1 + I[p];
}
void push(int p){
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
rev[p] = 0;
}
int get(int p){
return p == C[F[p]][1];
}
int root(int p){
return p != C[F[p]][0] && p != C[F[p]][1];
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(!root(f)) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
void update(int p){
if(!root(p)) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; !root(p); turn(p), f = F[p]){
if(!root(f)) turn(get(p) == get(f)? f : p);
}
}
int kabab(int p){
int c = 0;
for(; p; c = p, p = F[p]){
splay(p), I[p] += S[rc] - S[c], rc = c, pull(p);
}
return c;
}
void plant(int p){
p = kabab(p);
rev[p] ^= 1;
}
void link(int u, int v){
plant(u), splay(u), kabab(v), splay(v), F[u] = v, I[v] += S[u];
}
void cut(int u, int v){
plant(u), kabab(v), splay(u);
F[C[u][1]]= 0, C[u][1] = 0, pull(u);
}
signed main(){
char t;
int n, q, u, v;
cin >> n >> q;
for(int i = 1; i <= n; i++) S[i] = 1;
while(q--){
cin >> t >> u >> v;
if(t == 'A') link(u, v);
else{
cut(u, v);
plant(u), plant(v), splay(u), splay(v);
cout << S[u] * S[v] << "\n";
link(u, v);
}
}
return 0;
}
#include <bits/stdc++.h>
#define pb push_back
#define lc C[p][0]
#define rc C[p][1]
using namespace std;
struct edge{
int p, a, b;
};
array<int, 150004> F, M, B, L, R, rev;
array<array<int, 2>, 150004> C;
vector<edge> E;
bool cmp(edge a, edge b){
return a.a < b.a;
}
int min(int a, int b){
if(a < 0 || b < 0) return a < 0? b : a;
return a < b? a : b;
}
void pull(int p){
M[p] = max({M[lc], M[rc], B[p]});
}
void push(int p){
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
rev[p] = 0;
}
int get(int p){
return p == C[F[p]][1];
}
int root(int p){
return p != C[F[p]][0] && p != C[F[p]][1];
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(!root(f)) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
pull(f), pull(p);
}
void update(int p){
if(!root(p)) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; !root(p); turn(p), f = F[p]){
if(!root(f)) turn(get(p) == get(f)? f : p);
}
}
int kabab(int p){
int c = 0;
for(; p; c = p, p = F[p]){
splay(p), rc = c, pull(p);
}
return c;
}
void plant(int p){
p = kabab(p), rev[p] ^= 1;
}
int find(int p){
p = kabab(p);
for(; lc; push(p), p = lc);
return p;
}
void link(int u, int v){
plant(u), splay(u), F[u] = v;
}
void cut(int u, int v){
plant(u), kabab(v), splay(u);
C[u][1] = 0, F[v] = 0, pull(u);
}
int query(int p){
splay(p);
for(; p; push(p), p = M[lc] > M[rc]? lc : rc){
if(M[p] == B[p]) return p;
}
return 0;
}
signed main(){
int n, m, x, y, p, q, t, ans = -1;
cin >> n >> m;
for(int i = n + 1; i <= n + m; i++){
cin >> x >> y >> p >> q;
L[i] = x, R[i] = y, B[i] = q;
E.pb({i, p, q});
}
sort(E.begin(), E.end(), cmp);
for(auto [p, a, b] : E){
if(L[p] == R[p]) continue;
if(find(L[p]) == find(R[p])){
plant(L[p]), kabab(R[p]), t = query(L[p]);
if(B[t] <= b) continue;
cut(t, L[t]), cut(t, R[t]);
}
link(p, L[p]), link(p, R[p]);
if(find(1) == find(n)){
plant(1), kabab(n), splay(1);
ans = min(ans, a + M[1]);
}
}
cout << ans << "\n";
return 0;
}
#include <bits/stdc++.h>
#define pb push_back
#define lc C[p][0]
#define rc C[p][1]
using namespace std;
array<int, 300004> F, rev;
array<array<int, 2>, 300004> C;
array<pair<int, int>, 300004> W;
void push(int p){
if(rev[p]) swap(lc, rc);
rev[lc] ^= rev[p], rev[rc] ^= rev[p];
rev[p] = 0;
}
int get(int p){
return p == C[F[p]][1];
}
int root(int p){
return p != C[F[p]][0] && p != C[F[p]][1];
}
void turn(int p){
int f = F[p], g = get(p), c = C[p][!g];
if(!root(f)) C[F[f]][get(f)] = p;
F[p] = F[f], F[f] = p, C[p][!g] = f, C[f][g] = c;
if(c) F[c] = f;
}
void update(int p){
if(!root(p)) update(F[p]);
push(p);
}
void splay(int p){
update(p);
for(int f = F[p]; !root(p); turn(p), f = F[p]){
if(!root(f)) turn(get(f) == get(p)? f : p);
}
}
int kabab(int p){
int c = 0;
for(; p; c = p, p = F[p]){
splay(p), rc = c;
}
return c;
}
void plant(int p){
p = kabab(p);
rev[p] ^= 1;
}
int find(int p){
p = kabab(p);
for(; lc; push(p), p = lc);
return p;
}
void link(int u, int v){
plant(u), splay(u), F[u] = v;
}
void cut(int u, int v){
plant(u), kabab(v), splay(u);
F[v] = C[u][1] = 0;
}
signed main(){
int n, m, p, q, k = 1;
char t;
cin >> n >> m;
for(int i = 1; i < n; i++){
cin >> p >> q;
link(p, q);
}
while(m--){
cin >> t >> p;
if(t == 'Q'){
cin >> q;
cout << (find(p) == find(q)? "Yes\n" : "No\n");
}else if(t == 'C'){
cin >> q;
W[k++] = {p, q};
cut(p, q);
}else{
auto [a, b] = W[p];
link(a, b);
}
}
return 0;
}
嗷嗷待補