Bare topic, tree array interval modification + single point query. Of course, a little discussion about whether the left and right end of the chain is modified.
#include <cstdio> #include <algorithm> #include <cmath>using namespace std; #define N 300001int En,v[n <<1],first[n],next[n<<1],n;void Addedge (const int &u,const int &v) {v[++en]=v;next[en]=first[u]; first[u]=en;} int dep[n],siz[n],fa[n],son[n],top[n],num[n],tot;void dfs (int u,int d) {dep[u]=d; Siz[u]=1; for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]) {fa[v[i]]=u; DFS (V[I],D+1); Siz[u]+=siz[v[i]]; if (Siz[v[i]]>siz[son[u]]) son[u]=v[i]; }}void dfs2 (int U) {if (Son[u]) {top[son[u]]=top[u]; Num[son[u]]=++tot; DFS2 (Son[u]); } for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]&&v[i]!=son[u]) {top[v[i]]=v[i]; Num[v[i]]=++tot; DFS2 (V[i]); }}int siz[n],top[n],sz;void dfs3 (int U) {for (int i=first[u];i;i=next[i]) {if (V[i]!=fa[u]) {if (siz[ Top[u]]<sz) {ToP[v[i]]=top[u]; ++siz[top[u]]; } DFS3 (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;} int d[n];void add_node (int p,const int &v) {for (;p <=n;p+= (-P)) p&;} void Add_range (const int &l,const int &r) {Add_node (l,1), if (r!=n) Add_node (r+1,-1);} int query (int p) {int res=0;for (;p; p-= (-P)) Res+=d[p];return res;} void update (int u,int V) {int F1=top[u],f2=top[v];while (F1!=F2) {if (Dep[f1]<dep[f2]) {swap (F1,F2); Swap (U,V); } add_range (Num[f1],num[u]); U=FA[F1]; F1=top[u]; }if (Dep[u]>dep[v]) swap (U,V); Add_range (Num[u],num[v]);} int cnt,ll[n],rr[n];void dfs4 (int U) {ll[u]=++cnt;for (int i=first[u];i;i=next[i]) if (V[i]!=fa[u]) dfs4 (V[i]); rr[u]=cnt;} int xu[n];void work (const int &L,CONST int &r,const int &op) {if (op==n-1) {if (fa[l]==r| | FA[R]==L) return; int Lca=lca (L,R); if (lca==l) {for (int i=first[l];i;i=next[i]) if (v[i]!=fa[l]&&ll[r]>=ll[v[i]]&&ll[r]<=rr[v [i]]) {update (v[i],fa[r]); Return }} else if (lca==r) {for (int i=first[r];i;i=next[i]) if (v[i]!=fa[r]&&ll[l]>=ll[v[i]]&&l L[l]<=rr[v[i]] {update (fa[l],v[i]); Return }} else update (Fa[l],fa[r]); Return }if (LCA (l,r) ==l) {for (int i=first[l];i;i=next[i]) if (v[i]!=fa[l]&&ll[r]>=ll[v[i]]&&ll[r]<= Rr[v[i]] {update (V[I],R); Return }}else Update (FA[L],R);} int main () {int a,b;scanf ("%d", &n), for (int i=1;i<=n;++i) scanf ("%d", &xu[i]), and for (int i=1;i<n;++i) {scanf ("%d%d", &a,&b); Addedge (A, b); Addedge (B,a); }top[1]=1; Num[1]=++tot;dfs;d FS2 (1); sz=sqRT (n); if (!sz) sz=1; for (int i=1;i<=n;i++) {siz[i]=1; Top[i]=i; } dfs3 (1);d fs4 (1); if (n==2) {work (xu[2],xu[1],0); Goto out; }update (xu[1],xu[2]); for (int. i=2;i<n;++i) work (xu[i],xu[i+1],i); out:for (int i=1;i<=n;++i) printf ("%d\n", Query (Num[i]); return 0;}
Tree chain split, tree array, recent common ancestor, block tree bzoj3631 [JLOI2014] new home for squirrels