链剖,线段树记录左右端点即可
区间合并的顺序还是要注意一下,挺容易乱。。
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(i=l;i<=r;i++) 3 #define dec(i,l,r) for(i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 100000+5 10 using namespace std; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 15 return x*f; 16 } 17 struct info{ 18 int s,l,r,z; 19 }T[8*NM],null; 20 struct edge{ 21 int t; 22 edge *next; 23 }e[2*NM],*h[NM],*p=e; 24 int n,m,f[NM],son[NM],id[NM],_id[NM],a[NM],d[NM],top[NM],TOP,size[NM],tot; 25 int _x,_y,_v,l,r; 26 info operator+(const info&x,const info&y){ 27 info f; 28 if(x.s==-1)return y; 29 if(y.s==-1)return x; 30 f.l=x.l;f.r=y.r; 31 f.s=x.s+y.s; 32 if(x.r==y.l)f.s--; 33 f.z=-1; 34 return f; 35 } 36 void add(int x,int y){ 37 p->t=y;p->next=h[x];h[x]=p;p++; 38 } 39 void dfs1(int x){ 40 link(x) 41 if(!f[j->t]){ 42 f[j->t]=x; 43 d[j->t]=d[x]+1; 44 dfs1(j->t); 45 size[x]+=size[j->t]; 46 if(size[j->t]>size[son[x]])son[x]=j->t; 47 } 48 size[x]++; 49 } 50 void dfs2(int x){ 51 top[x]=TOP;id[x]=++tot;_id[tot]=x; 52 if(son[x])dfs2(son[x]); 53 link(x) 54 if(!top[j->t])dfs2(TOP=j->t); 55 } 56 void pushdown(int i){ 57 if(T[i].z>=0){ 58 T[i<<1].s=T[i<<1|1].s=1; 59 T[i<<1].l=T[i<<1].r=T[i<<1|1].l=T[i<<1|1].r=T[i].z; 60 T[i<<1].z=T[i<<1|1].z=T[i].z; 61 T[i].z=-1; 62 } 63 } 64 void build(int i,int x,int y){ 65 int t=x+y>>1; 66 if(x==y){ 67 T[i].s=1;T[i].z=-1; 68 T[i].l=T[i].r=a[_id[x]]; 69 return; 70 } 71 build(i<<1,x,t);build(i<<1|1,t+1,y); 72 T[i]=T[i<<1]+T[i<<1|1]; 73 } 74 void ch(int i,int x,int y){ 75 int t=x+y>>1; 76 if(l<=x&&y<=r){ 77 T[i].s=1;T[i].l=T[i].r=_v;T[i].z=_v; 78 return; 79 } 80 if(l>y||r<x)return; 81 pushdown(i); 82 ch(i<<1,x,t);ch(i<<1|1,t+1,y); 83 T[i]=T[i<<1]+T[i<<1|1]; 84 } 85 info query(int i,int x,int y){ 86 int t=x+y>>1; 87 if(l<=x&&y<=r)return T[i]; 88 if(y<l||r<x)return null; 89 pushdown(i); 90 return query(i<<1,x,t)+query(i<<1|1,t+1,y); 91 } 92 int main(){ 93 int i; 94 n=read();m=read(); 95 inc(i,1,n)a[i]=read(); 96 inc(i,1,n-1){ 97 _x=read();_y=read(); 98 add(_x,_y);add(_y,_x); 99 } 100 f[1]=1;null.s=-1; 101 dfs1(1); 102 dfs2(TOP=1); 103 build(1,1,n); 104 while(m--){ 105 char opt[10]; 106 info tx=null,ty=null; 107 scanf("%s",opt);_x=read();_y=read(); 108 if(opt[0]=='C'){ 109 _v=read(); 110 while(top[_x]!=top[_y]){ 111 if(d[top[_x]]<d[top[_y]])swap(_x,_y); 112 l=id[top[_x]];r=id[_x]; 113 ch(1,1,n); 114 _x=f[top[_x]]; 115 } 116 if(d[_x]>d[_y])swap(_x,_y); 117 l=id[_x];r=id[_y]; 118 ch(1,1,n); 119 }else{ 120 while(top[_x]!=top[_y]) 121 if(d[top[_x]]>d[top[_y]]){ 122 l=id[top[_x]];r=id[_x]; 123 tx=query(1,1,n)+tx; 124 _x=f[top[_x]]; 125 }else{ 126 l=id[top[_y]];r=id[_y]; 127 ty=query(1,1,n)+ty; 128 _y=f[top[_y]]; 129 } 130 swap(ty.l,ty.r);swap(tx.l,tx.r); 131 if(d[_x]<d[_y]){ 132 l=id[_x];r=id[_y]; 133 tx=tx+query(1,1,n); 134 }else{ 135 l=id[_y];r=id[_x]; 136 ty=ty+query(1,1,n); 137 } 138 swap(ty.l,ty.r); 139 tx=tx+ty; 140 printf("%d\n",tx.s); 141 } 142 } 143 return 0; 144 }