题目链接:http://www.spoj.com/problems/OTOCI/
LCT模板题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N = 30006;
const int M = N << 1;
inline int max(int a, int b, int c) {
return max(a, max(b, c));
}
struct LinkCutTree {
int p[N], val[N], sumv[N], l[N], r[N];
bool rev[N], rt[N];
int n;
#define lu l[u]
#define ru r[u]
#define pu p[u]
#define pv p[v]
void init(int n) {
this->n = n;
for (int i = 1; i <= n; i++) {
p[i] = 0;
rt[i] = 1;
l[i] = 0, r[i] = 0, rev[i] = 0;
}
}
inline void Set(int* a, int u, int v) {
a[u] = v, pv = u;
}
inline void push_up(int u) {
sumv[u] = sumv[lu] + sumv[ru] + val[u];
}
inline void push_down(int u) {
if (u == 0) return;
if (rev[u]) {
swap(lu, ru);
rev[lu] ^= 1, rev[ru] ^= 1;
rev[u] = 0;
}
}
inline void rotate(int u) {
int v = pu;
if (rt[v])
pu = pv;
else {
push_down(pv);
Set(pu == l[pv] ? l : r, pv, u);
}
push_down(v), push_down(u);
if (u == l[v]) {
Set(l, v, ru);
Set(r, u, v);
}
else {
Set(r, v, lu);
Set(l, u, v);
}
if (rt[v]) rt[u] = 1, rt[v] = 0;
push_up(v);
}
void Splay(int u) {
while (!rt[u]) {
rotate(u);
}
}
int Access(int u) {
int v = 0;
do {
Splay(u), push_down(u);
rt[ru] = 1, rt[ru = v] = 0, push_up(u);
u = p[v = u];
} while (u);
return v;
}
void Evert(int u) {
rev[Access(u)] ^= 1;
}
int Root(int u) {
for (u = Access(u); push_down(u), lu; u = lu);
return u;
}
void Link(int u, int v) {
if (Root(u) == Root(v))
puts("no");
else {
Evert(u), Splay(u), p[u] = v, Access(u);
puts("yes");
}
}
void Query(int u, int v) {
if (Root(u) != Root(v))
puts("impossible");
else {
Access(v), v = 0;
do {
Splay(u), push_down(u);
if (!p[u]) printf("%d\n", sumv[ru] + sumv[v] + val[u]);
rt[ru] = 1, rt[ru = v] = 0, push_up(u);
u = p[v = u];
} while (u);
}
}
void reset(int u, int d) {
Splay(u);
val[u] = d;
push_up(u);
}
}T;
char str[36];
int main() {
int n, m, a, b;
scanf("%d", &n);
T.init(n);
for (int i = 1; i <= n; i++) {
scanf("%d", &T.val[i]);
T.sumv[i] = T.val[i];
}
scanf("%d", &m);
for (int i = 0; i < m; i++) {
scanf("%s%d%d", str, &a, &b);
if (str[0] == 'e')
T.Query(a, b);
else if (str[0] == 'b')
T.Link(a, b);
else
T.reset(a, b);
}
return 0;
}