被自己蠢哭了。
原来LCT即是在一开始的每个点输入一个点权的阶段也不能直接upd啊,还得Splay。。。。。。
LCT:
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define inf 0x3f3f3f3f
#define maxn 30005
using namespace std;
int n,m;
int fa[maxn],ch[maxn][2],Max[maxn],Sum[maxn],val[maxn];
bool rev[maxn],tp[maxn];
inline void upd(int now)
{
Max[now]=max(max(Max[ch[now][0]],Max[ch[now][1]]),val[now]);
Sum[now]=Sum[ch[now][0]]+Sum[ch[now][1]]+val[now];
}
inline void dcd(int now)
{
if(rev[now])
{
rev[now]=0;
swap(ch[now][0],ch[now][1]);
(ch[now][0]) && (rev[ch[now][0]] ^= 1);
(ch[now][1]) && (rev[ch[now][1]] ^= 1);
}
}
inline void Rotate(int x)
{
if(!x || tp[x]) return;
dcd(x);
int y=fa[x],z=fa[y],c=(ch[y][1]==x);
(ch[y][c]=ch[x][!c]) && (fa[ch[y][c]]=y);
fa[fa[ch[x][!c]=y]=x]=z;
if(!tp[y]) ch[z][ch[z][1]==y]=x;
else swap(tp[y],tp[x]);
swap(rev[y],rev[x]);
upd(y),upd(x);
}
void Splay(int x)
{
dcd(x);
for(int y;!tp[x];Rotate(x))
if((y=fa[x]) && !tp[y])
if((ch[y][1]==x)==(ch[fa[y]][1]==y)) Rotate(y);
else Rotate(x);
dcd(x);
}
int Access(int x)
{
for(int y=0;;upd(x),y=x,x=fa[x])
{
if(!x) return y;
Splay(x);
(ch[x][1]) && (tp[ch[x][1]]=1);
(ch[x][1]=y) && (tp[y]=0);
}
}
void Bert(int x)
{
Access(x),Splay(x);
rev[x]^=1;dcd(x);
}
void Split(int x,int y){Bert(x),Access(y),Splay(y);}
void Change(int x,int w){ Splay(x),val[x]=w,upd(x); }
int Qmax(int x,int y){ Split(x,y);return Max[y]; }
int Qsum(int x,int y){ Split(x,y);return Sum[y]; };
void Link(int x,int y){ Bert(x),fa[x]=y; }
int main()
{
//freopen("1.in","r",stdin);
Sum[0]=0,Max[0]=-inf;
scanf("%d",&n);
memset(Max,-0x3f,sizeof Max);
memset(tp,1,sizeof tp);
memset(rev,0,sizeof rev);
for(int i=1,u,v;i<n;i++)
{
scanf("%d%d",&u,&v);
Link(u,v);
}
for(int i=1;i<=n;i++)
scanf("%d",&val[i]),
Splay(i),upd(i);
scanf("%d",&m);
char ch[8];
int u,v;
for(;m--;)
{
scanf("%s%d%d",ch,&u,&v);
if(ch[0]=='C') Change(u,v);
else
{
if(ch[1]=='M') printf("%d\n",Qmax(u,v));
else printf("%d\n",Qsum(u,v));
}
}
}
树剖:
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define inf 0x3f3f3f3f
#define lc now<<1
#define rc now<<1|1
#define maxn 30005
using namespace std;
int n,m;
int info[maxn],Prev[maxn*2],to[maxn*2],cnt_e;
inline void Node(int u,int v){ Prev[++cnt_e]=info[u],info[u]=cnt_e ,to[cnt_e]=v;}
int dep[maxn],fa[maxn],tp[maxn],siz[maxn],son[maxn],id[maxn],cnt_id;
void dfs1(int now,int ff)
{
dep[now]=dep[fa[now]=ff]+1;
siz[now]=1,son[now]=-1;
for(int i=info[now];i;i=Prev[i])
if(to[i]!=ff)
{
dfs1(to[i],now);
siz[now]+=siz[to[i]];
(son[now]==-1 || siz[to[i]]>siz[son[now]]) && (son[now]=to[i]);
}
}
void dfs2(int now,int ff,int anc)
{
id[now]=++cnt_id,tp[now]=anc;
if(son[now]!=-1) dfs2(son[now],now,anc);
for(int i=info[now];i;i=Prev[i])
if(to[i]!=ff && to[i]!=son[now])
dfs2(to[i],now,to[i]);
}
int Max[maxn*10],Sum[maxn*10];
inline void upd(int now){ Max[now]=max(Max[lc],Max[rc]);Sum[now]=Sum[lc]+Sum[rc]; }
void Insert(int now,int l,int r,int pos,int val)
{
if(l>pos || r<pos) return;
if(l==r){ Max[now]=Sum[now]=val;return; }
int mid=(l+r)>>1;
Insert(lc,l,mid,pos,val);
Insert(rc,mid+1,r,pos,val);
upd(now);
}
int Qmax(int now,int l,int r,int ql,int qr)
{
if(l>qr || r<ql) return -inf;
if(ql<=l && r<=qr) return Max[now];
int mid=(l+r)>>1;
return max(Qmax(lc,l,mid,ql,qr),Qmax(rc,mid+1,r,ql,qr));
}
int Qsum(int now,int l,int r,int ql,int qr)
{
if(l>qr || r<ql) return 0;
if(ql<=l && r<=qr) return Sum[now];
int mid=(l+r)>>1;
return Qsum(lc,l,mid,ql,qr)+Qsum(rc,mid+1,r,ql,qr);
}
int Qmax(int u,int v)
{
int ret=-inf;
for(;tp[u]!=tp[v];)
{
if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
ret=max(ret,Qmax(1,1,n,id[tp[v]],id[v]));
v=fa[tp[v]];
}
if(dep[u]>dep[v]) swap(u,v);
return max(Qmax(1,1,n,id[u],id[v]),ret);
}
int Qsum(int u,int v)
{
int ret=0;
for(;tp[u]!=tp[v];)
{
if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
ret+=Qsum(1,1,n,id[tp[v]],id[v]);
v=fa[tp[v]];
}
if(dep[u]>dep[v]) swap(u,v);
return ret+Qsum(1,1,n,id[u],id[v]);
}
int main()
{
int u,v;
char ch[8];
scanf("%d",&n);
for(int i=1;i<n;i++) scanf("%d%d",&u,&v),Node(u,v),Node(v,u);
dfs1(1,0),dfs2(1,0,1);
for(int i=1;i<=n;i++) scanf("%d",&u),Insert(1,1,n,id[i],u);
scanf("%d",&m);
for(;m--;)
{
scanf("%s%d%d",ch,&u,&v);
if(ch[1]=='H') Insert(1,1,n,id[u],v);
if(ch[1]=='M') printf("%d\n",Qmax(u,v));
if(ch[1]=='S') printf("%d\n",Qsum(u,v));
}
}