Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
Sample Output
4
1
2
2
10
6
5
6
5
16
1
2
2
10
6
5
6
5
16
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<queue>
#define INF 2147483640
#define eps 1e-9
#define MAXN 30010
using namespace std;
int n,q,u[MAXN],s[MAXN],v[MAXN],ch[MAXN][2],value[MAXN],maxn[MAXN],fa[MAXN];
long long sum[MAXN];
bool lazy[MAXN];
inline bool isroot(int x)
{
return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
}
void push_up(int x)
{
sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + value[x];
maxn[x] = max(value[x],max(maxn[ch[x][0]],maxn[ch[x][1]]));
}
void rotate(int x)
{
int y = fa[x],z = fa[y];
int d = ch[y][0] == x ? 0 : 1;
if(!isroot(y))
{
if(ch[z][0] == y) ch[z][0] = x;
else ch[z][1] = x;
}
fa[y] = x,fa[x] = z,fa[ch[x][d^1]] = y;
ch[y][d] = ch[x][d^1],ch[x][d^1] = y;
push_up(y),push_up(x);
}
inline void push_down(int x)
{
if(!lazy[x]) return;
lazy[x]^=1,lazy[ch[x][0]]^=1;lazy[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
}
void splay(int x)
{
int tot = 0;
for(int i = x;!isroot(i);i = fa[i]) s[++tot] = fa[i];
for(;tot;tot--) push_down(s[tot]);
while(!isroot(x))
{
int y = fa[x],z = fa[y];
push_down(y);push_down(x);
if(!isroot(y))
{
if((ch[z][0] == y) ^ (ch[y][0] == x)) rotate(x);
else rotate(y);
}
rotate(x);
}
push_down(x);
}
void access(int x)
{
int t = 0;
while(x)
{
splay(x);
ch[x][1] = t;
push_up(x);
t = x,x = fa[x];
}
}
void makeroot(int x) //x变成根
{
access(x),splay(x);
lazy[x]^=1;
}
void link(int x,int y)
{
makeroot(x);fa[x] = y;
}
void cut(int x,int y)
{
makeroot(x),access(y),splay(y),
ch[y][0] = fa[x] = 0;
push_up(y);
}
int main()
{
maxn[0] = -INF;
scanf("%d",&n);
for(int i = 1;i < n;i++) scanf("%d%d",&u[i],&v[i]);
for(int i = 1;i <= n;i++)
{
scanf("%d",&value[i]);
maxn[i] = sum[i] = value[i];
}
for(int i = 1;i < n;i++) link(u[i],v[i]);
scanf("%d",&q);
for(int i = 1;i <= q;i++)
{
char op[6];int x,y;
scanf("%s",op);
scanf("%d %d",&x,&y);
if(op[1] == 'M')
{
makeroot(x);
access(y);
splay(y);
printf("%d\n",maxn[y]);
}
if(op[1] == 'S')
{
makeroot(x);
access(y);
splay(y);
printf("%lld\n",sum[y]);
}
if(op[1] == 'H')
{
splay(x);
value[x] = y;
push_up(x);
}
}
}
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<queue>
#define INF 2147483640
#define eps 1e-9
#define MAXN 30010
using namespace std;
int n,q,u[MAXN],s[MAXN],v[MAXN],ch[MAXN][2],value[MAXN],maxn[MAXN],fa[MAXN];
long long sum[MAXN];
bool lazy[MAXN];
inline bool isroot(int x)
{
return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
}
void push_up(int x)
{
sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + value[x];
maxn[x] = max(value[x],max(maxn[ch[x][0]],maxn[ch[x][1]]));
}
void rotate(int x)
{
int y = fa[x],z = fa[y];
int d = ch[y][0] == x ? 0 : 1;
if(!isroot(y))
{
if(ch[z][0] == y) ch[z][0] = x;
else ch[z][1] = x;
}
fa[y] = x,fa[x] = z,fa[ch[x][d^1]] = y;
ch[y][d] = ch[x][d^1],ch[x][d^1] = y;
push_up(y),push_up(x);
}
inline void push_down(int x)
{
if(!lazy[x]) return;
lazy[x]^=1,lazy[ch[x][0]]^=1;lazy[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
}
void splay(int x)
{
int tot = 0;
for(int i = x;!isroot(i);i = fa[i]) s[++tot] = fa[i];
for(;tot;tot--) push_down(s[tot]);
while(!isroot(x))
{
int y = fa[x],z = fa[y];
push_down(y);push_down(x);
if(!isroot(y))
{
if((ch[z][0] == y) ^ (ch[y][0] == x)) rotate(x);
else rotate(y);
}
rotate(x);
}
push_down(x);
}
void access(int x)
{
int t = 0;
while(x)
{
splay(x);
ch[x][1] = t;
push_up(x);
t = x,x = fa[x];
}
}
void makeroot(int x) //x变成根
{
access(x),splay(x);
lazy[x]^=1;
}
void link(int x,int y)
{
makeroot(x);fa[x] = y;
}
void cut(int x,int y)
{
makeroot(x),access(y),splay(y),
ch[y][0] = fa[x] = 0;
push_up(y);
}
int main()
{
maxn[0] = -INF;
scanf("%d",&n);
for(int i = 1;i < n;i++) scanf("%d%d",&u[i],&v[i]);
for(int i = 1;i <= n;i++)
{
scanf("%d",&value[i]);
maxn[i] = sum[i] = value[i];
}
for(int i = 1;i < n;i++) link(u[i],v[i]);
scanf("%d",&q);
for(int i = 1;i <= q;i++)
{
char op[6];int x,y;
scanf("%s",op);
scanf("%d %d",&x,&y);
if(op[1] == 'M')
{
makeroot(x);
access(y);
splay(y);
printf("%d\n",maxn[y]);
}
if(op[1] == 'S')
{
makeroot(x);
access(y);
splay(y);
printf("%lld\n",sum[y]);
}
if(op[1] == 'H')
{
splay(x);
value[x] = y;
push_up(x);
}
}
}