作为一名OI选手初二小朋友,我还是觉得静态的LCT好写,于是推翻了以前幼稚的代码虽然以前的动态版本也放在下面了,大爷们勿喷
静态:
#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for (register int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
typedef long long LL;
inline int read()
{
int c = getchar(), fg = 1, sum = 0;
while (c < '0' || c > '9') { if (c == '-') fg = -1; c = getchar(); }
while (c >= '0' && c <= '9') sum = sum * 10 + c - '0', c = getchar();
return sum * fg;
}
const int maxn = 300000, oo = 0x3f3f3f3f;
int N, M;
struct LCT
{
#define L ch][0
#define R ch][1
int val[maxn + 5], Max[maxn + 5], add[maxn + 5], rev[maxn + 5];
int ch[maxn + 5][2], pre[maxn + 5];
inline bool is_root(const int &x) { return x != x[pre][L] && x != x[pre][R]; }
void init(const int *value)
{
REP(i, 0, N ? N : maxn)
{
i[val] = i[Max] = i[value];
i[rev] = i[add] = i[pre] = i[L] = i[R] = 0;
}
0[val] = 0[Max] = -oo;
}
inline void push_up(const int &x)
{
x[Max] = x[val];
if (x[L]) chkmax(x[Max], x[L][Max]);
if (x[R]) chkmax(x[Max], x[R][Max]);
}
inline void push_down(const int &x)
{
if (x[add])
{
if (x[L]) x[L][val] += x[add], x[L][Max] += x[add], x[L][add] += x[add];
if (x[R]) x[R][val] += x[add], x[R][Max] += x[add], x[R][add] += x[add];
x[add] = 0;
}
if (x[rev])
{
swap(x[L], x[R]);
if (x[L]) x[L][rev] ^= 1;
if (x[R]) x[R][rev] ^= 1;
x[rev] = 0;
}
}
inline void rotate(const int &x)
{
register int y = x[pre], T = x == y[R];
x[ch][!T][pre] = y;
y[ch][T] = x[ch][!T];
x[pre] = y[pre];
if (y == y[pre][L]) y[pre][L] = x;
else if (y == y[pre][R]) y[pre][R] = x;
y[pre] = x;
x[ch][!T] = y;
push_up(y), push_up(x);
}
inline void push_tag(int x)
{
static int stack[maxn + 5], top; top = 0;
while (!is_root(x)) stack[top++] = x, x = x[pre];
push_down(x);
while (top) push_down(stack[--top]);
}
inline void splay(int x)
{
push_tag(x);
while (!is_root(x))
{
int y = x[pre], z = y[pre];
if (is_root(y)) rotate(x);
else if ((z[L] == y) == (y[L] == x))
rotate(y), rotate(x);
else rotate(x), rotate(x);
}
push_up(x);
}
inline int access(int x)
{
int y = 0;
while (x)
{
splay(x);
x[R] = y;
push_up(x);
y = x;
x = x[pre];
}
return y;
}
inline void change_root(const int &x)
{
access(x)[rev] ^= 1;
splay(x);
}
inline int get_root(int x)
{
access(x);
splay(x);
while (x[L]) x = x[L];
splay(x);
return x;
}
inline void link(const int &x, const int &y)
{
change_root(x);
x[pre] = y;
access(x);
}
inline void cut(const int &x, const int &y)
{
change_root(x);
access(y), splay(y);
y[L] = y[L][pre] = 0;
push_up(y);
}
inline void update(int x, int y, int w)
{
change_root(x);
y = get_root(y);
y[Max] += w, y[val] += w, y[add] += w;
}
inline int query(int x, int y)
{
change_root(x);
y = get_root(y);
return y[Max];
}
inline bool p(int x, int y)
{
while (x[pre]) x = x[pre];
while (y[pre]) y = y[pre];
return x == y;
}
};
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
return 0;
}
动态:
#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define DREP(i, a, b) for (int i = (a), i##_start_ = (b); i >= i##_start_; --i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()
template<typename T> inline bool chkmin(T &a, const T &b){ return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b){ return a < b ? a = b, 1 : 0; }
typedef long long LL;
const int dmax = 300100, oo = 0x3f3f3f3f;
int n, m;
struct node
{
node *f, *ch[2];
int val, max, rev, add;
}c[dmax], *cur, *Null;
#define L ch[0]
#define R ch[1]
node *new_node(int k)
{
cur->val = cur->max = k;
cur->rev = cur->add = 0;
cur->f = cur->L = cur->R = Null;
return cur++;
}
void init()
{
Null = c;
Null->f = Null->L = Null->R = Null;
Null->val = Null->max = -oo;
Null->rev = Null->add = 0;
cur = c + 1;
}
struct lct
{
inline bool is_root(node *t) { return t == Null || t->f->L != t && t->f->R != t; }
inline void push_up(node *t) { t->max = max(t->val, max(t->L->max, t->R->max)); }
inline void push_down(node *t)
{
if (t->rev)
{
if (t->L != Null) t->L->rev ^= 1;
if (t->R != Null) t->R->rev ^= 1;
t->rev = 0;
swap(t->L, t->R);
}
if (t->add)
{
if (t->L != Null) t->L->val += t->add, t->L->max += t->add, t->L->add += t->add;
if (t->R != Null) t->R->val += t->add, t->R->max += t->add, t->R->add += t->add;
t->add = 0;
}
}
inline void rotate(node *x)
{
if (is_root(x)) return;
node *y = x->f;
int k = x == y->R;
x->f = y->f;
y->ch[k] = x->ch[!k];
if (x->ch[!k] != Null) x->ch[!k]->f = y;
if (!is_root(y))
{
if (y == y->f->L)
y->f->L = x;
else y->f->R = x;
}
x->ch[!k] = y;
y->f = x;
push_up(y);
}
void splay(node *x)
{
static node *S[dmax];
int top = 1;
S[0] = x;
for (node *Cur = x; !is_root(Cur); Cur = Cur->f)
S[top++] = Cur->f;
while (top > 0) push_down(S[--top]);
while (!is_root(x))
{
node *y = x->f;
if (!is_root(y))
rotate(x);
else{
if (x == y->f->L->L || x == y->f->R->R)
rotate(y);
else rotate(x);
rotate(x);
}
}
push_up(x);
}
node *access(node *x)
{
node *y = Null;
while (x != Null)
{
splay(x);
x->R = y;
y->f = x;
push_up(x);
y = x;
x = x->f;
}
return y;
}
inline void change_root(node *x) { access(x)->rev ^= 1; splay(x); }
inline void link(node *x, node *y)
{
change_root(x);
x->f = y;
access(x);
}
inline void cut(node *x)
{
access(x);
splay(x);
x->L = x->L->f = Null;
push_up(x);
}
node *get_root(node *x)
{
access(x);
splay(x);
while (x->L != Null) x = x->L;
splay(x);
return x;
}
bool p(node *x, node *y)
{
while (x->f != Null) x = x->f;
while (y->f != Null) y = y->f;
return x == y;
}
}t;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
return 0;
}