当前位置: 代码迷 >> 综合 >> P3313 [SDOI2014]旅行
  详细解决方案

P3313 [SDOI2014]旅行

热度:22   发布时间:2023-10-29 17:22:24.0

树链剖分+有颜色的线段树

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
using namespace std;
const int M=4120000,N=420000;
int tot,cnt,n,m,root[N],nex[2*N],head[N],to[2*N],c[N],d[N],f[N],dep[N];
int size[N],son[N],top[N],id[N],cnt2,v1[N],v2[N],q;
struct node{int ls,rs,sum,maxn,num;node(){ls=rs=maxn=sum=0;}
}t[M];
void add(int x,int y){nex[++tot]=head[x];to[tot]=y;head[x]=tot;}
void dfs1(int x){size[x]=1;dep[x]=dep[f[x]]+1;for(int i=head[x],tmp;i;i=nex[i]){if((tmp=to[i])==f[x]) continue;f[tmp]=x;dfs1(tmp);if(size[son[x]]<size[tmp]) son[x]=tmp;size[x]+=size[tmp];}
}
void dfs2(int x,int t){top[x]=t;id[x]=++cnt2;v1[cnt2]=c[x];v2[cnt2]=d[x];if(!son[x])return;dfs2(son[x],t);for(int i=head[x];i;i=nex[i])if(!id[to[i]]) dfs2(to[i],to[i]);
}
void update(int x){t[x].sum=t[t[x].ls].sum+t[t[x].rs].sum;t[x].maxn=max(t[t[x].ls].maxn,t[t[x].rs].maxn);
}void modify(int &o,int l,int r,int id,int d){if(id>r||id<l) return ;if(!o) o=++cnt;if(l==r&&l==id){t[o].sum=t[o].maxn=d;return ;}int mid=(l+r)>>1;modify(t[o].ls,l,mid,id,d);modify(t[o].rs,mid+1,r,id,d);update(o);if(t[o].sum==0) o=0;
}
int querymax(int o,int l,int r,int ql,int qr){if(l>qr||r<ql||!o) return 0;if(l>=ql&&r<=qr) return t[o].maxn;int mid=(l+r)>>1;return max(querymax(t[o].ls,l,mid,ql,qr),querymax(t[o].rs,mid+1,r,ql,qr));
}
int querysum(int o,int l,int r,int ql,int qr){if(l>qr||r<ql||!o) return 0;if(l>=ql&&r<=qr) return t[o].sum;int mid=(l+r)>>1;return querysum(t[o].ls,l,mid,ql,qr)+querysum(t[o].rs,mid+1,r,ql,qr);
}
int get_max(int x,int y,int w){int ans=0;while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);ans=max(querymax(root[c[w]],1,n,id[top[x]],id[x]),ans);x=f[top[x]];}if(dep[x]<dep[y]) swap(x,y);ans=max(querymax(root[c[w]],1,n,id[y],id[x]),ans);return ans;
}
int get_sum(int x,int y,int w){int ans=0;while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);ans=querysum(root[c[w]],1,n,id[top[x]],id[x])+ans;x=f[top[x]];}if(dep[x]<dep[y]) swap(x,y);ans=querysum(root[c[w]],1,n,id[y],id[x])+ans;return ans;
}
int main(){scanf("%d%d",&n,&q);for(int i=1;i<=n;i++) scanf("%d%d",&d[i],&c[i]); for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);dfs1(1);dfs2(1,1);for(int i=1;i<=n;i++) modify(root[v1[i]],1,n,i,v2[i]);while(q--){
   char s[20];cin>>s;int x,y;scanf("%d%d",&x,&y);if(s[1]=='C') modify(root[c[x]],1,n,id[x],0),c[x]=y,modify(root[c[x]],1,n,id[x],d[x]);else if(s[1]=='W') d[x]=y,modify(root[c[x]],1,n,id[x],y);else if(s[1]=='M') printf("%d\n",get_max(x,y,y));else printf("%d\n",get_sum(x,y,y));}
}