记录编号 356734 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2008]树的统计Count 最终得分 100
用户昵称 Gravatarsxysxy 是否通过 通过
代码语言 C++ 运行时间 1.998 s
提交时间 2016-12-06 11:21:14 内存使用 0.90 MiB
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <cstring>
#include <list>
#include <queue>
#include <vector>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
struct node
{
    node *ch[2], *f;
    #define LC ch[0]
    #define RC ch[1]
    int data;
    int maxv;
    int rev;
    int sum;
    void reverse()
    {
        if(!this)return;
        rev ^= 1;
        swap(LC, RC);
    }
    void pushdown()
    {
        if(!this)return;
        if(rev)
        {
            ch[0]->reverse();
            ch[1]->reverse();
            rev = 0;
        }
    }
    void pushup()
    {
        maxv = max(data, max(LC->maxv, RC->maxv));
        sum = data+LC->sum+RC->sum;
    }
}_null_node;
node *make_null()
{
    node *p = &_null_node;
    p->f = p->LC = p->RC = 0;
    p->maxv = -0x7fffffff;
    p->sum = 0;
    p->rev = 0;
    p->data = 0;
    return p;
}
node *null = make_null();
node *new_node(int v)
{
    node *d = new node();
    d->LC = d->RC = d->f = null;
    d->data = d->sum = d->maxv = v;
    d->rev = 0;
    return d;
}
inline bool is_root(node *x)
{
    return x==null || (x != x->f->LC && x != x->f->RC);
}
void rotate(node *x)
{
    if(is_root(x))return;
    node *f = x->f;
    if(!is_root(f))
    {
        if(f == f->f->LC)f->f->LC = x;
        else f->f->RC = x;
    }
    x->f = f->f;
    int d = (x==f->RC);
    f->ch[d] = x->ch[d^1];
    if(x->ch[d^1] != null)x->ch[d^1]->f = f;
    x->ch[d^1] = f;
    f->f = x;
    f->pushup();
    x->pushup();
}
void splay(node *x)
{
    x->pushdown();
    while(!is_root(x))
    {
        node *f = x->f;
        node *ff = f->f;
        ff->pushdown();
        f->pushdown();
        x->pushdown();
        if(is_root(f))
            rotate(x);
        else
        {
            if(x == ff->LC->LC || x == ff->RC->RC)
                rotate(f);else rotate(x);
            rotate(x);
        }
    }
}
void access(node *x)
{
    node *m = null;
    while(x != null)
    {
        splay(x);
        x->RC = m;
        if(m != null)m->f = x;
        x->pushup();
        m = x;
        x = x->f;
    }
}
void make_root(node *x)
{
    access(x);
    splay(x);
    x->reverse();
}
void link(node *t, node *m)
{
    make_root(t);
    t->f = m;
    access(t);
}
char buf[1<<18], *fs, *ft;
inline char readc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<18,stdin),fs==ft))?0:*fs++;
}
int fast_read()
{
    int r;
    char c;
    bool s = false;
    while(c = readc())
    {
        if(c >= '0' && c <= '9')
        {
            r = c^0x30;
            break;
        }else if(c == '-')s = true;
    }
    while(isdigit(c = readc()))
        r = (r<<3)+(r<<1)+(c^0x30);
    return s?-r:r;
}
node *ns[30002];
struct edge
{
    int u, v;
}es[30002];
int main()
{
    freopen("bzoj_1036.in", "r", stdin);
    freopen("bzoj_1036.out", "w", stdout);
    int n = fast_read();
    for(int i = 1; i < n; i++)
    {
        es[i].u = fast_read();
        es[i].v = fast_read();
    }
    for(int i = 1; i <= n; i++)ns[i] = new_node(fast_read());
    for(int i = 1; i < n; i++)
        link(ns[es[i].u], ns[es[i].v]);
    int q = fast_read();
    while(q--)
    {
        char c, cp;
        int x, y;
        while(!isalpha(c = readc()));
        cp = readc();
        x = fast_read();
        y = fast_read();
        if(c == 'Q')
        {
            if(cp == 'M')
            {
                make_root(ns[x]);
                access(ns[y]);
                splay(ns[y]);
                printf("%d\n", ns[y]->maxv);
            }else
            {
                make_root(ns[x]);
                access(ns[y]);
                splay(ns[y]);
                printf("%d\n", ns[y]->sum); 
            }
        }else
        {
            access(ns[x]);
            splay(ns[x]);
            ns[x]->data = y;
            ns[x]->pushup();
        }
    }
    return 0;
}