您的位置:首页 > 其它

1036: [ZJOI2008]树的统计Count

2016-02-25 11:32 155 查看
链剖

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define N 30000+10
#define INF 1000000000
#define L(x) to[x][0]
#define R(x) to[x][1]
int n,m,fa
,to
[2],num
,mmax
,sum
;
bool mark
;
void Up(int x)
{
sum[x]=sum[L(x)]+sum[R(x)]+num[x];
mmax[x]=max(num[x],max(mmax[L(x)],mmax[R(x)]));
}
void Pushdown(int x)
{
if(!mark[x])return ;
mark[x]=false;
swap(L(x),R(x));
mark[L(x)]^=1;
mark[R(x)]^=1;
}
bool Is(int x)
{
return L(fa[x])!=x&&R(fa[x])!=x;
}bool ok=false;
void Rotate(int x)
{
int y=fa[x],z=fa[y];
Pushdown(y);Pushdown(x);
if(!Is(y)) to[z][to[z][1]==y]=x;
int c=to[y][1]==x;
fa[x]=z;fa[y]=x;fa[to[x][c^1]]=y;
to[y][c]=to[x][c^1];to[x][c^1]=y;
Up(y);Up(x);
}
void Splay(int x)
{

Pushdown(x);
while(!Is(x))
{
if(!Is(fa[x])) Rotate(fa[x]);
Rotate(x);
}
}
void Access(int x)
{
int t=0;
while(x)
{
Splay(x);
R(x)=t;
t=x;Up(x);

x=fa[x];
}
}
void Markroot(int x)
{
Access(x);Splay(x);mark[x]^=1;
}
void Change(int x,int y)
{
Splay(x);num[x]=y;Up(x);
}
void Link(int x,int y)
{
Markroot(x);fa[x]=y;
}
int F(int x,int y)
{
Markroot(x);Pushdown(x);Access(y);Splay(y);R(y)=0;Up(y);
return y;
}
int main()
{
cin>>n;int x,y;mmax[0]=-INF;
for(int i=1;i<n;i++) scanf("%d %d",&x,&y),Link(x,y);
for(int i=1;i<=n;i++) scanf("%d",&x),Change(i,x);
cin>>m;
char s[100];
while(m--)
{
scanf("%s %d %d",s+1,&x,&y);
switch(s[2])
{
case 'H':Change(x,y);break;
case 'M':printf("%d\n",mmax[F(x,y)]);break;
case 'S':printf("%d\n",sum[F(x,y)]);break;
}
}
return 0;
}


LCT
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: