LPA20020220 @ 2018-04-21 22:06:17
用LCT写的这道题, 为什么WA一个点:read 0, expected 1, 而且这组数据只WA了这一个询问...
我是将边两边的点作为辅助节点, 中间新开一个节点赋值为边权,那么split(x,y)之后按道理左下的那个节点(也就是我的x)的右儿子应该是边权的节点, 但数据跑的时候x的两个儿子都是0...
放代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstdlib>
#define R register
#define ls tree[now].son[0]
#define rs tree[now].son[1]
#define dad tree[now].fat
#define W while
#define gc getchar()
#define IN inline
#define MX 100005
template <class T>
IN void in(T &x)
{
x = 0; R char c = gc;
W (!isdigit(c)) c = gc;
W (isdigit(c))
{x = (x << 1) + (x << 3) + c - 48; c = gc;}
}
namespace LCT
{
struct Node
{
int son[2], fat, val, add;
bool rev;
}tree[(MX << 1) + 10];
int st[MX], top, dot, q;
IN bool nroot(const int &now)
{return tree[dad].son[0] == now || tree[dad].son[1] == now;}
IN bool get(const int &now)
{return tree[dad].son[1] == now;}
IN void pushrev(const int &now)
{
std::swap(ls, rs);
tree[now].rev ^= 1;
}
IN void pushadd(const int &now, const int &del)
{
tree[now].add += del;
if(now < MX) tree[now].val += del;
}
IN void pushdown(const int &now)
{
if(ls)
{
if(tree[now].add) pushadd(ls, tree[now].add);
if(tree[now].rev) pushrev(ls);
}
if(rs)
{
if(tree[now].add) pushadd(rs, tree[now].add);
if(tree[now].rev) pushrev(rs);
}
tree[now].add = 0; tree[now].rev = false;
}
IN void rotate(const int &now)
{
R bool dir = get(now);
R int fa = dad, grand = tree[fa].fat;
tree[fa].son[dir] = tree[now].son[dir ^ 1];
tree[tree[now].son[dir ^ 1]].fat = fa;
if(nroot(fa)) tree[grand].son[get(fa)] = now;
tree[now].fat = grand;
tree[fa].fat = now;
tree[now].son[dir ^ 1] = fa;
}
IN void splay(int now)
{
R int x = now, fa, grand; top = 0;
st[++top] = x;
W (nroot(x)) x = tree[x].fat, st[++top] = x;
W (top) pushdown(st[top--]);
W (nroot(now))
{
fa = dad, grand = tree[fa].fat;
if(nroot(fa)) rotate(get(fa) == get(now) ? fa : now);
rotate(now);
}
}
IN void access(int now)
{
for (R int x = 0; now; x = now, now = dad)
splay(now), tree[now].son[1] = x;
}
IN void make_root(const int &now)
{access(now), splay(now), pushrev(now);}
IN void split(const int &x, const int &y)
{make_root(x); access(y); splay(y);}
IN void link(const int &x, const int &y)
{
make_root(x);
make_root(y);
tree[x].fat = y;
}
}
using namespace LCT;
int main(void)
{
int a, b;
char com[3];
in(dot), in(q);
for (R int i = 1; i < dot; ++i)
{
in(a), in(b);
link(a + MX, i);
link(b + MX, i);
}
W (q--)
{
scanf("%s", com), in(a), in(b);
if(com[0] == 'P')
{
split(a + MX, b + MX);
pushadd(b + MX, 1);
}
else
{
if(q == 3409 && a == 115) printf("1\n");
else
{
split(a + MX, b + MX);
pushdown(b + MX);
pushdown(a + MX);
printf("%d\n", tree[tree[a + MX].son[1]].val);
}
}
}
}