Topic: Given a tree, each point has a weight and a color, several times to change the weights and colors of some points, multiple times to find a path with the beginning and end of the same color of the point of the weight and the weight value of the maximum value
Each color opens a segment tree dynamically open nodes each point only builds one chain so the spatial complexity is O (NLOGN)
And then we'll just split the normal tree chain.
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define M 100100using namespace std;struct abcd{int to,next;} Table[m<<1];struct Segtree{segtree *ls,*rs;int Sum,max_num; Segtree (): LS (0x0), RS (0x0), sum (0), max_num (0) {}}*tree[m];int head[m],tot;int n,m;int w[m],c[m];int fa[m],son[m],dpt[ M],size[m],pos[m],top[m],cnt;void Update (segtree* &p,int x,int y,int z,int v) {int mid=x+y>>1;if (!p) p=new Segtree;if (x==y) {P->sum=p->max_num=v;return;} if (z<=mid) update (P->LS,X,MID,Z,V), Else Update (p->rs,mid+1,y,z,v);p->sum= (p->ls?p->ls->sum : 0) + (p->rs?p->rs->sum:0);p->max_num=max ((p->ls?p->ls->max_num:0), (p->rs?p->rs-> max_num:0));} int Get_sum (segtree *p,int x,int y,int l,int r) {int mid=x+y>>1;if (!P) return 0;if (x==l&&y==r) return p-> Sum;if (R<=mid) return Get_sum (P->ls,x,mid,l,r), if (L>mid) return get_sum (p->rs,mid+1,y,l,r); return Get_sum (P->ls,x,mid,l,mid) + get_sum (p->rs,mid+1,y,mid+1,r);} int Get_max (segtree *p,int x,int y,int l,int r) {int mid=x+y>>1;if (!P) return 0;if (x==l&&y==r) return p-> Max_num;if (R<=mid) return Get_max (P->ls,x,mid,l,r), if (L>mid) return Get_max (P->RS,MID+1,Y,L,R); return Max (Get_max (P->ls,x,mid,l,mid), Get_max (P->rs,mid+1,y,mid+1,r));} void Add (int x,int y) {table[++tot].to=y;table[tot].next=head[x];head[x]=tot;} void DFS1 (int x) {int i;dpt[x]=dpt[fa[x]]+1;size[x]=1;for (i=head[x];i;i=table[i].next) {if (table[i].to==fa[x]) CONTINUE;FA[TABLE[I].TO]=X;DFS1 (table[i].to); Size[x]+=size[table[i].to];if (Size[table[i].to]>size[son[x]) son[x]=table[i].to;}} void DFS2 (int x) {int i;pos[x]=++cnt;if (son[fa[x]]==x) top[x]=top[fa[x]];elsetop[x]=x; Update (Tree[c[x]],1,n,pos[x],w[x]), if (Son[x]) DFS2 (Son[x]), for (I=head[x];i;i=table[i].next) {if (table[i].to==fa[ x]| | TABLE[I].TO==SON[X]) CONTINUE;DFS2 (table[i].to);}} int query_sum (int x,int y,int _c) {int fx=top[x],fy=top[y],rE=0;while (fx!=fy) {if (Dpt[fx]<dpt[fy]) swap (x, y), swap (FX,FY); Re+=get_sum (Tree[_c],1,n,pos[fx],pos[x]); x=fa[fx ];FX=TOP[X];} if (Dpt[x]<dpt[y]) swap (x, y); Re+=get_sum (Tree[_c],1,n,pos[y],pos[x]); return re;} int Query_max (int x,int y,int _c) {int Fx=top[x],fy=top[y],re=0;while (FX!=FY) {if (Dpt[fx]<dpt[fy]) swap (x, y), swap ( FX,FY); Re=max (Re,get_max (tree[_c],1,n,pos[fx],pos[x)); x=fa[fx];fx=top[x];} if (Dpt[x]<dpt[y]) swap (x, y); Re=max (Re,get_max (tree[_c],1,n,pos[y],pos[x)); return re;} int main () {int I,x,y;char p[10];cin>>n>>m;for (i=1;i<=n;i++) scanf ("%d%d", &w[i],&c[i]); for (i =1;i<n;i++) scanf ("%d%d", &x,&y), add (x, y), add (y,x);D FS1 (1);D FS2 (1); for (i=1;i<=m;i++) {scanf ("%s%d%d ", p,&x,&y); switch (p[1]) {case ' C ': Update (tree[c[x]],1,n,pos[x],0); Update (tree[c[x]=y],1,n,pos[x],w[x]); Break;case ' W ': Update (tree[c[x]],1,n,pos[x],w[x]=y); Break;case ' S ':p rintf (" %d\n ", Query_sum (X,y,c[x])) break;case ' M ':p rintf ("%d\n ", Query_max (X,y,c[x]));
Bzoj 3531 SDOI2014 travel tree chain split