#include <cstdio> #include <cstring> #include <algorithm> #include <cmath>using namespace std;# Define N 50001int v[n<<1],en,first[n],next[n<<1];void addedge (int u,int v) {v[++en]=v; Next[en]=first[u]; first[u]=en;} int n,m,a[n],b[n];int eq,ec,blo,sz,siz[n],top[n],fa[n],dep[n],num[n];void DFS (int U) {for (int i=first[u];i;i=next[i] ) if (V[i]!=fa[u]) {fa[v[i]]=u; dep[v[i]]=dep[u]+1; if (Siz[top[u]]<sz) {++siz[top[u]]; Top[v[i]]=top[u]; } dfs (V[i]); }}void df2 (int U) {num[u]=blo; for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]&&top[v[i]]==top[u]) DF2 (V[i]);} int LCA (int u,int V) {while (u!=v) {if (Top[u]!=top[v]) {if (Dep[top[u]]<dep[top[v]) Swap (U,V); U=fa[top[u]]; } else {if (Dep[u]<dep[v]) swap (U,V); U=fa[u]; }} return U;} struct Upt{int x, y, Z;} Ch[n];struct ask{int l,r,p,t;} Q[n];bool operator < (const ask &a,const ask &b) {if (NUM[A.L]==NUM[B.L]) {if (NUM[A.R]==NUM[B.R] ) Return a.t<b.t; Return num[a.r]<num[b.r]; } return NUM[A.L]<NUM[B.L];} int nu2[n],r[230],l[230],sumv[230],bl2=1,t[n];void Makeblock () {int sz=sqrt (N); if (!sz) sz=0; R[0]=-1; for (; bl2*sz<n;++bl2) {l[bl2]=r[bl2-1]+1; R[bl2]=bl2*sz; for (int i=l[bl2];i<=r[bl2];++i) NU2[I]=BL2; } l[bl2]=r[bl2-1]+1; R[bl2]=n; for (int i=l[bl2];i<=r[bl2];++i) NU2[I]=BL2;} void Update (int x,int op) {if (x>=n) return; T[x]+=op; if (! T[X])--sumv[nu2[x]; else if (op==1&&t[x]==1) ++sumv[nu2[x]];} BOOL Vis[n];void Work (int. u,int V,int LCA) {while (U!=LCA) {vis[u]^=1; Update (a[u],vis[u]?1:-1); U=fa[u]; } while (V!=LCA) { Vis[v]^=1; Update (a[v],vis[v]?1:-1); V=FA[V]; }}int Query () {for (Int. i=1;i<=bl2;++i) if (sumv[i]<r[i]-l[i]+1) for (int j=l[i];j<=r[i];++j) if (! T[J]) return J; BOOL Op[n];int Anss[n];int Main () {int x, y; scanf ("%d%d", &n,&m); for (int i=1;i<=n;++i) scanf ("%d", &a[i]); for (int i=1;i<n;++i) {scanf ("%d%d", &x,&y); Addedge (x, y); Addedge (Y,X); } for (int i=1;i<=n;++i) {top[i]=i; Siz[i]=1; } sz= (int) Pow ((double) n,2.0/3.0); DFS (1); for (int i=1;i<=n;++i) if (top[i]==i) {++blo; DF2 (i); } memcpy (b,a,sizeof (int) * (n+1)); for (int i=1;i<=m;++i) {scanf ("%d", &op[i]); if (!op[i]) {++ec; scanf ("%d%d", &ch[ec].x,&ch[ec].y); Ch[ec].z=b[ch[ec].x]; B[CH[EC].X]=CH[EC].Y; } ELSE {++EQ; scanf ("%d%d", &Q[EQ].L,&Q[EQ].R); Q[eq].t=ec; Q[eq].p=eq; }} makeblock (); Sort (q+1,q+eq+1); for (int i=1;i<=q[1].t;++i) a[ch[i].x]=ch[i].y; int Lca=lca (Q[1].L,Q[1].R); Work (Q[1].L,Q[1].R,LCA); Update (a[lca],1); Anss[q[1].p]=query (); Update (a[lca],-1); for (int i=2;i<=eq;++i) {if (q[i-1].t<q[i].t) for (int j=q[i-1].t+1;j<=q[i].t;++j) { if (vis[ch[j].x]) {Update (ch[j].y,1); Update (a[ch[j].x],-1); } a[ch[j].x]=ch[j].y; } else for (int j=q[i-1].t;j>q[i].t;--j) {if (vis[ch[j].x]) {UPD Ate (ch[j].z,1); Update (a[ch[j].x],-1); } a[ch[j].x]=ch[j].z; } work (Q[i-1].l,q[i].l,lca (Q[I-1].L,Q[I].L)); Work (Q[i-1].r,q[i].r,lca (Q[I-1].R,Q[I].R)); Lca=lca (Q[i].L,Q[I].R); Update (a[lca],1); Anss[q[i].p]=query (); Update (a[lca],-1); } for (int i=1;i<=eq;++i) printf ("%d\n", Anss[i]); return 0;}
"bzoj4129" on the tree "with the team" "Weight Block" Haruna ' s breakfast