# BZOJ 3786

$$n \leq 1\times 10^5,m \leq 3\times 10^5$$

const int MAXN = 100000 + 5;

struct Input {
char buf[1 << 25], *s;

Input() {
#ifdef LOCAL
freopen("BZOJ3786.in", "r", stdin);
freopen("BZOJ3786.out", "w", stdout);
#endif
fread(s = buf, 1, 1 << 25, stdin);
}

friend Input &operator>>(Input &io, int &x) {
x = 0;
while (!isdigit(*io.s))
++ io.s;
while (isdigit(*io.s))
x = x * 10 + *io.s ++ - '0';
return io;
}

friend Input &operator>>(Input &io, char *s) {
while (isspace(*io.s))
++ io.s;
while (!isspace(*io.s))
*s ++ = *io.s ++;
return io;
}
} cin;

int arr[MAXN * 2];
bool ok[MAXN * 2];

struct Splay {
struct Node {
Node *fa, *ch[2];
bool ok;
LL sum;

Node() {}
Node(Node *p, int v, bool o) : fa(p), sz(1), val(v), addv(0), ok(o), sum(v) {
ch[0] = ch[1] = NULL;
}

bool relation() {
return this == fa->ch[1];
}

#define _sz(x) ((x) ? (x)->sz : 0)
#define _sum(x) ((x) ? (x)->sum : 0)
void push_up() {
sz = _sz(ch[0]) + (ok ? 1 : -1) + _sz(ch[1]);
sum = _sum(ch[0]) + val + _sum(ch[1]);
}

void push_down() {
FOR(i, 0, 2)
if (ch[i]) {
ch[i]->sum += 1LL * addv * ch[i]->sz;
}
}
}
} *nd[MAXN * 2];

Node *build(Node *par, int l, int r) {
if (l > r)
return NULL;
int mid = (l + r) >> 1;
nd[mid] = new Node(par, arr[mid], ok[mid]);
nd[mid]->ch[0] = build(nd[mid], l, mid - 1);
nd[mid]->ch[1] = build(nd[mid], mid + 1, r);
nd[mid]->push_up();
return nd[mid];
}

void rotate(Node *o) {
int t = o->relation();
Node *par = o->fa;
par->ch[t] = o->ch[t ^ 1];
if (o->ch[t ^ 1])
o->ch[t ^ 1]->fa = par;
if (par->fa)
par->fa->ch[par->relation()] = o;
o->fa = par->fa, o->ch[t ^ 1] = par, par->fa = o;
par->push_up();
o->push_up();
}

void splay(Node *o) {
static Node *stk[MAXN * 2];
int top = 0;
for (Node *tmp = o; tmp; tmp = tmp->fa)
stk[++ top] = tmp;
Rep(i, top, 1)
stk[i]->push_down();
for (; o->fa; rotate(o))
if (o->fa->fa)
rotate(o->fa->relation() == o->relation() ? o->fa : o);
}

Node *split(Node *o, int d) {
splay(o);
Node *p = o->ch[d];
if (p)
p->fa = NULL;
o->ch[d] = NULL;
o->push_up();
return p;
}

Node *min(Node *o) {
Node *k = o;
for (; k->ch[0]; k = k->ch[0]);
return k;
}

Node *max(Node *o) {
Node *k = o;
for (; k->ch[1]; k = k->ch[1]);
return k;
}

void merge(Node *o, Node *p) {
if (!o || !p)
return;
Node *q = max(o);
splay(q);
splay(p);
q->ch[1] = p;
p->fa = q;
q->push_up();
}

std::pair <Node *, Node *> select(Node *l, Node *r) {
std::pair <Node *, Node *> res;
res.F = split(l, 0), res.S = split(r, 1);
return res;
}

LL query(Node *l, Node *r) {
std::pair <Node *, Node *> tmp = select(l, r);
splay(l);
LL ans = l->sum;
merge(tmp.F, l);
merge(l, tmp.S);
return ans;
}

void modify(Node *l, Node *r, int x) {
std::pair <Node *, Node *> tmp = select(l, r);
splay(l);
l->val += l->ok ? x : -x;
l->sum += 1LL * l->sz * x;
merge(tmp.F, l);
merge(l, tmp.S);
}

void change(Node *l, Node *r, Node *target) {
std::pair <Node *, Node *> tmp = select(l, r);
merge(tmp.F, tmp.S);
Node *c = split(target, 1);
merge(target, l);
merge(l, c);
}
} S;

struct Tree {
int hed[MAXN], nxt[MAXN * 2], to[MAXN * 2], val[MAXN], fa[MAXN], L[MAXN], R[MAXN], cnt, dfn;

void add_edge(int u, int v) {
++ cnt;
to[cnt] = v;
nxt[cnt] = hed[u];
hed[u] = cnt;
}

void DFS(int u) {
++ dfn;
arr[dfn] = val[u];
ok[dfn] = 1;
L[u] = dfn;
for (int e = hed[u]; e; e = nxt[e]) {
int v = to[e];
if (v != fa[u]) {
fa[v] = u;
DFS(v);
}
}
++ dfn;
arr[dfn] = -val[u];
ok[dfn] = 0;
R[u] = dfn;
}
} T;

int main() {
int n;
cin >> n;
For(i, 2, n) {
int par;
cin >> par;
}
For(i, 1, n)
cin >> T.val[i];
T.DFS(1);
S.build(NULL, 1, n * 2);
int m;
cin >> m;
For(i, 1, m) {
static char opt[5];
cin >> opt;
if (opt[0] == 'Q') {
int d;
cin >> d;
printf("%lld\n", S.query(S.nd[1], S.nd[T.L[d]]));
} else if (opt[0] == 'C') {
int x, y;
cin >> x >> y;
S.change(S.nd[T.L[x]], S.nd[T.R[x]], S.nd[T.L[y]]);
} else {
int p, q;
cin >> p >> q;
S.modify(S.nd[T.L[p]], S.nd[T.R[p]], q);
}
}
return 0;
}

posted @ 2018-10-13 00:08  sjkmost  阅读(202)  评论(0编辑  收藏  举报