好吧本来看到就是一道裸地树剖嘛。。然后差错差了一个晚上。。发现时线段树下传标记的时候坑了
连线段树都打不来了QAQ
计算答案的时候需要注意一下其他什么都好说
突然发现其实我的程序还是很好看的(误
#include<cstdio> #include<iostream> #include<cstring> using namespace std; char c; inline void read(int &a) { a=0;do { c=getchar(); }while(c<'0'||c>'9'); while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar(); } struct Data { int l_c,r_c; int D; inline friend Data operator +(Data a,Data b) { Data c; if(a.D==-1)return b; if(b.D==-1)return a; c.D=(a.r_c==b.l_c)?(a.D+b.D-1):(a.D+b.D); c.l_c=a.l_c; c.r_c=b.r_c; return c; } }; inline Data rev(Data a) { return (Data){a.r_c,a.l_c,a.D}; } int Color[200001]; int Heavy_Chain_Node[200001],Heavy_Chain_Place[200001],Heavy_Chain_Begin[200001],Heavy_Chain_End[200001]; int Size[200001],Heavy_Son[200001],F[200001]; int Deep[200001]; int Con; struct Chain{int u;Chain *next;Chain(){next=NULL;}}*Head[200001]; inline void addside(int a,int b) { Chain *tp=new Chain; tp->next=Head[a]; tp->u=b; Head[a]=tp; } void DFS(int u,int fa) { Size[u]++; F[u]=fa; Heavy_Son[u]=0; for(Chain *tp=Head[u];tp;tp=tp->next) if(tp->u!=fa) { Deep[tp->u]=Deep[u]+1; DFS(tp->u,F[tp->u]=u); Size[u]+=Size[tp->u]; if(Size[Heavy_Son[u]]<Size[tp->u]) Heavy_Son[u]=tp->u; } } void DFS2(int u,int Begin,int fa) { Heavy_Chain_Begin[u]=Begin; Heavy_Chain_Place[u]=++Con; Heavy_Chain_Node[Con]=u; if(Heavy_Son[u]) DFS2(Heavy_Son[u],Begin,u); Heavy_Chain_End[u]=Con; for(Chain *tp=Head[u];tp;tp=tp->next) if(tp->u!=Heavy_Son[u]&&tp->u!=fa) DFS2(tp->u,Con+1,u); } struct Segement { int l,r; Data D; bool lazy; }Segement_Tree[500001]; void Segement_Build(int place,int l,int r) { Segement_Tree[place].l=l; Segement_Tree[place].r=r; Segement_Tree[place].lazy=false; if(l^r) { Segement_Build(place<<1,l,(l+r)>>1); Segement_Build(place<<1|1,((l+r)>>1)+1,r); Segement_Tree[place].D=Segement_Tree[place<<1].D+Segement_Tree[place<<1|1].D; return ; } else Segement_Tree[place].D=(Data){Color[Heavy_Chain_Node[l]],Color[Heavy_Chain_Node[l]],1}; } inline void pushdown(int place) { Segement_Tree[place<<1].D= Segement_Tree[place<<1|1].D= Segement_Tree[place].D; Segement_Tree[place<<1|1].lazy= Segement_Tree[place<<1].lazy=true; Segement_Tree[place].lazy=false; } inline void Segement_Modify(int place,int l,int r,Data D) { if(Segement_Tree[place].l>=l&&Segement_Tree[place].r<=r) { Segement_Tree[place].D=D; Segement_Tree[place].lazy=true; return ; } if(Segement_Tree[place].l^Segement_Tree[place].r) if(Segement_Tree[place].lazy) pushdown(place); if(l<=Segement_Tree[place<<1].r) Segement_Modify(place<<1,l,r,D); if(r>=Segement_Tree[place<<1|1].l) Segement_Modify(place<<1|1,l,r,D); Segement_Tree[place].D=Segement_Tree[place<<1].D+Segement_Tree[place<<1|1].D; Segement_Tree[place].lazy=false; } Data Segement_Query(int place,int l,int r) { if(Segement_Tree[place].l>=l&&Segement_Tree[place].r<=r) return Segement_Tree[place].D; if(Segement_Tree[place].l^Segement_Tree[place].r) if(Segement_Tree[place].lazy) pushdown(place); Data res; res.D=-1; if(l<=Segement_Tree[place<<1].r) res=Segement_Query(place<<1,l,r); if(r>=Segement_Tree[place<<1|1].l) res=res+Segement_Query(place<<1|1,l,r); return res; } inline Data Query(int x,int y) { Data xx,yy; xx.D=yy.D=-1; while(Heavy_Chain_Begin[x]^Heavy_Chain_Begin[y]) { if(Deep[Heavy_Chain_Node[Heavy_Chain_Begin[x]]]>=Deep[Heavy_Chain_Node[Heavy_Chain_Begin[y]]]) xx=Segement_Query(1,Heavy_Chain_Begin[x],Heavy_Chain_Place[x])+xx,x=F[Heavy_Chain_Node[Heavy_Chain_Begin[x]]]; else yy=Segement_Query(1,Heavy_Chain_Begin[y],Heavy_Chain_Place[y])+yy,y=F[Heavy_Chain_Node[Heavy_Chain_Begin[y]]]; } if(Deep[x]<=Deep[y]) return rev(xx)+Segement_Query(1,Heavy_Chain_Place[x],Heavy_Chain_Place[y])+yy; return rev(yy)+Segement_Query(1,Heavy_Chain_Place[y],Heavy_Chain_Place[x])+xx; } inline void Modify(int x,int y,int c) { Data D; D.l_c=D.r_c=c; D.D=1; while(Heavy_Chain_Begin[x]^Heavy_Chain_Begin[y]) { if(Deep[Heavy_Chain_Node[Heavy_Chain_Begin[x]]]>=Deep[Heavy_Chain_Node[Heavy_Chain_Begin[y]]]) Segement_Modify(1,Heavy_Chain_Begin[x],Heavy_Chain_Place[x],D),x=F[Heavy_Chain_Node[Heavy_Chain_Begin[x]]]; else Segement_Modify(1,Heavy_Chain_Begin[y],Heavy_Chain_Place[y],D),y=F[Heavy_Chain_Node[Heavy_Chain_Begin[y]]]; } if(Deep[x]<=Deep[y]) Segement_Modify(1,Heavy_Chain_Place[x],Heavy_Chain_Place[y],D); Segement_Modify(1,Heavy_Chain_Place[y],Heavy_Chain_Place[x],D); } int main() { int n,m,i,j,k; read(n),read(m); for(i=1;i<=n;i++) read(Color[i]); for(i=1;i<n;i++)read(j),read(k),addside(j,k),addside(k,j); DFS(1,1); DFS2(1,1,1); Segement_Build(1,1,Con); int a,b,c; char ch; while(m--) { do ch=getchar();while(ch!='Q'&&ch!='C'); if(ch=='C') { read(a),read(b),read(c); Modify(a,b,c); } else { read(a),read(b); printf("%d\n",Query(a,b).D); } } return 0; }