[SDOI2014]旅行
Link
Solution
挺简单的一道题,对每种颜色开一棵动态开点的线段树,然后树剖查询即可。
就当是复习一下树剖,然后规范一下写法。主要是记录一下代码。
#include<stdio.h>
const int N=1e5+7;
inline int read(){
int x=0,flag=1; char c=getchar();
while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
return flag? x:-x;
}
struct Node{
Node(int ls_=0,int rs_=0,int mx_=0,int s_=0)
:ls(ls_),rs(rs_),mx(mx_),s(s_){}
int ls,rs,mx,s;
}t[N*20];
struct Init{
int c,w;
}a[N];
struct E{
int next,to;
}e[N<<1];
const int C=1e5;
int n,Q,in[N];
int head[N],sz[N],fa[N],son[N],top[N],dep[N];
inline int max(int x,int y){return x>y? x:y;}
inline void add(int id,int to){
static int cnt=0;
e[++cnt]=(E){head[id],to};
head[id]=cnt;
}
void dfs(int u){
sz[u]=1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]) continue;
dep[v]=dep[u]+1,fa[v]=u;
dfs(v),sz[u]+=sz[v];
if(sz[son[u]]<sz[v]) son[u]=v;
}
}
void Dfs(int u,int tp){
static int cnt=0;
in[u]=++cnt,top[u]=tp;
if(!son[u]) return ;
Dfs(son[u],tp);
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==son[u]||v==fa[u]) continue;
Dfs(v,v);
}
}
int W,pos;
void modify(int &id,int lf=1,int rf=n){
static int cnt=C;
if(!id) id=++cnt;
if(lf==rf){t[id].s+=W,t[id].mx+=W;return;}
int mid=(lf+rf)>>1;
if(pos<=mid) modify(t[id].ls,lf,mid);
else modify(t[id].rs,mid+1,rf);
t[id].s=t[t[id].ls].s+t[t[id].rs].s;
t[id].mx=max(t[t[id].ls].mx,t[t[id].rs].mx);
}
void merge(Node &x,const Node &y){
x.mx=max(x.mx,y.mx);
x.s+=y.s;
}
int L,R;
Node query(int id,int lf=1,int rf=n){
if(!id) return (Node){0,0,0,0};
if(L<=lf&&rf<=R) return t[id];
int mid=(lf+rf)>>1; Node tmp;
if(L<=mid) merge(tmp,query(t[id].ls,lf,mid));
if(R>mid) merge(tmp,query(t[id].rs,mid+1,rf));
return tmp;
}
inline void swap(int &x,int &y){x^=y,y^=x,x^=y;}
Node Query(int u,int v){
Node ans; int rt=a[u].c;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
L=in[top[u]],R=in[u];
merge(ans,query(rt));
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
L=in[v],R=in[u],merge(ans,query(rt));
return ans;
}
int main(){
n=read(),Q=read();
for(int i=1;i<=n;i++)
a[i].w=read(),a[i].c=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
add(u,v),add(v,u);
}
dep[1]=1,dfs(1),Dfs(1,1);
for(int i=1;i<=n;i++)
W=a[i].w,pos=in[i],modify(a[i].c);
char opt[5];
while(Q--){
scanf("%s",opt);
int x=read(),y=read();
if(opt[1]=='C'){
W=-a[x].w,pos=in[x],modify(a[x].c);
W=a[x].w,modify(a[x].c=y);
}else if(opt[1]=='W')
W=y-a[x].w,pos=in[x],modify(a[x].c),a[x].w=y;
else{
Node p=Query(x,y);
printf("%d\n",opt[1]=='S'? p.s:p.mx);
}
}
}