以【清华集训2016】温暖会指引我们前行 为例
UOJ 274
#include
#include
#define R register
#define Null b
#define Min(_A, _B) (_A < _B ? _A : _B)
const int Inf = 2147483647;
struct Data{ int val, tmp, len, sum; bool rev; Data *Pre, *Son[2]; } b[400010];
bool check_root(R Data *Now){ return (Now->Pre->Son[0] != Now && Now->Pre->Son[1] != Now); }
template <class TT> void Swap(TT &A, TT &B){ R TT tt = A; A = B, B = tt; }
void Pushdown(R Data *Now){ if(Now->rev) Now->rev = 0, Swap(Now->Son[0], Now->Son[1]), Now->Son[0]->rev ^= 1, Now->Son[1]->rev ^= 1; }
void Pushup(R Data *Now)
{
Now->sum = Now->Son[0]->sum + Now->Son[1]->sum + Now->len;
Now->tmp = Min(Now->Son[0]->tmp, Min(Now->Son[1]->tmp, Now->val));
}
void Preview(R Data *Now){ if(!check_root(Now)) Preview(Now->Pre); Pushdown(Now); }
void Rotate(R Data *Now)
{
R Data *f = Now->Pre;
R int d = (f->Son[1] == Now);
(f->Son[d] = Now->Son[!d])->Pre = f;
Now->Pre = f->Pre;
if(!check_root(f)) f->Pre->Son[f->Pre->Son[1] == f] = Now;
(Now->Son[!d] = f)->Pre = Now;
Pushup(f);
}
void Splay(R Data *Now)
{
Preview(Now);
while(!check_root(Now))
{
if(!check_root(Now->Pre)) Rotate((Now->Pre->Pre->Son[0] == Now->Pre) ^ (Now->Pre->Son[0] == Now) ? Now : Now->Pre);
Rotate(Now);
}
Pushup(Now);
}
void Query_min(R Data *A, R Data *&Tmp)
{
if(A->val < Tmp->val) Tmp = A;
if(A->val == A->tmp) return ;
if(A->Son[0]->tmp < A-> Son[1]->tmp) Query_min(A->Son[0], Tmp);
else Query_min(A->Son[1], Tmp);
}
void Access(R Data *A){ R Data *last = Null; while(A != Null){ Splay(A), A->Son[1] = last; Pushup(A), last = A, A = A->Pre; } }
void Make_Root(R Data *A){ Access(A); Splay(A); A->rev ^= 1; }
void Link(R Data *A, R Data *B){ Make_Root(A), A->Pre = B, Access(A); }
void Cut(R Data *A, R Data *B){ Make_Root(A), Access(B), Splay(B), A->Pre = B->Son[0] = Null; Pushup(B); }
Data *Find_Root(R Data *A)
{
Access(A); Splay(A);
while(A->Son[0] != Null) A = A->Son[0]; return A;
}
int U[300010], V[300010];
bool vis[300010];
int main()
{
b[0] = (Data){Inf, Inf, 0, 0, 0, Null, {Null, Null}};
int n, m;
scanf("%d %d", &n, &m);
for(R int i = 1; i <= n; i++) b[i] = b[0];
for(R int i = 1; i <= m; i++)
{
R char str[10];
scanf("%s", str);
if(str[0] == 'f')
{
R int Id, u, v, t, l;
scanf("%d %d %d %d %d", &Id, &u, &v, &t, &l);
u++, v++, Id++;
R Data *A = Find_Root(b + u), *B = Find_Root(b + v);
b[Id + n] = (Data){t, t, l, l, 0, Null, {Null, Null}};
if(A == B)
{
Make_Root(b + u), Access(b + v); Splay(b + u), Query_min(b + u, A = b + u); // printf("%d ?\n", A - b);
if(A->val >= t){ Splay(A); continue; }
Cut(A, b + U[A - b - n]), Cut(A, b + V[A - b - n]); vis[A - b - n] = 0;
}
vis[Id] = 1; U[Id] = u, V[Id] = v;
Link(b + u, b + Id + n), Link(b + Id + n, b + v);
}
else if(str[0] == 'm')
{
R int u, v;
scanf("%d %d", &u, &v);
u++, v++;
R Data *A = Find_Root(b + u), *B = Find_Root(b + v);
if(A != B){ puts("-1"); continue; }
Make_Root(b + u), Access(b + v); Splay(b + v);
printf("%d\n", b[v].sum);
}
else
{
R int Id, l;
scanf("%d %d", &Id, &l);
Id++;
if(vis[Id]) b[Id + n].len = l, Splay(b + Id + n);
}
}
return 0;
}