Consider the set a[i] as the precursor point of the I point set, build a DAG, and create a new super-source S, to each precursor set to an empty point edge, then B[i] is the S-to-I set of required points.
First, using the Lengauer-tarjan algorithm to establish a dominator tree starting with S, then B[i] is all the ancestors of I in the tree.
For a query, construct a virtual tree, and then count the number of points on each edge of the virtual tree, accumulate.
Time Complexity $o (n+m+q\log N) $.
#include <cstdio> #include <algorithm>using namespace Std;const int N=200010,m=500010;int n,m,q,i,x,q[n],a [N],vis[n],tot,t,ans;int G1[n],g2[n],gd[n],v[m*3+n],nxt[m*3+n],ed;int Cnt,dfn[n],id[n],fa[n],f[n],mn[n],sd[n], Idom[n];int d[n],size[n],son[n],top[n],st[n],en[n];inline void Read (int&a) {char c;while (!) ( ((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')); a=c-' 0 '; while (((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')) (a*= Ten) +=c-' 0 ';} inline void Add (int*g,int x,int y) {v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} int F (int x) {if (f[x]==x) return x; int y=f (f[x]); if (Sd[mn[x]]>sd[mn[f[x]]]) mn[x]=mn[f[x]; return f[x]=y;} void Dfs (int x) {id[dfn[x]=++cnt]=x; for (int i=g1[x];i;i=nxt[i]) if (!dfn[v[i]) DFS (V[i]), fa[dfn[v[i]]]=dfn[x];} void Tarjan (int S) {int i,j,k,x; for (cnt=0,i=1;i<=n;i++) gd[i]=dfn[i]=id[i]=fa[i]=idom[i]=0,f[i]=sd[i]=mn[i]=i; DFS (S); for (i=n;i>1;i--) {for (j=g2[id[i]];j;j=nxt[j]) F (K=dfn[v[j]),sd[i]=sd[i]<sd[mn[k]]?sd[i]:sd[mn[k]]; Add (gd,sd[i],i); for (j=gd[F[I]=X=FA[I]];J;J=NXT[J]) F (K=v[j]),idom[k]=sd[mn[k]]<x?mn[k]:x; gd[x]=0; } for (I=2;i<=n;add (gd,idom[i],i), i++) if (Idom[i]!=sd[i]) idom[i]=idom[idom[i]];} void dfs1 (int x) {d[x]=d[idom[x]]+1,size[x]=1; for (int i=gd[x];i;i=nxt[i]) {DFS1 (V[i]), Size[x]+=size[v[i]]; if (Size[v[i]]>size[son[x]]) son[x]=v[i]; }}void dfs2 (int x,int y) {top[x]=y;st[x]=++cnt; if (Son[x]) DFS2 (son[x],y); for (int i=gd[x];i;i=nxt[i]) if (v[i]!=son[x]) DFS2 (V[i],v[i]); en[x]=cnt;} inline int LCA (int x,int y) {for (; Top[x]!=top[y];x=idom[top[x]]) if (D[top[x]]<d[top[y]]) swap (x, y); return d[x]<d[y]?x:y;} inline int cmp (int x,int y) {return st[x]<st[y];} int main () {for (read (n), n++,i=1;i<n;i++) {read (M); if (!m) Add (g1,n,i), add (g2,i,n); while (m--) read (x), add (G1,x,i), add (g2,i,x); } Tarjan (n), CNT=0,DFS1 (1), DFS2 (); for (read (Q); q--;p rintf ("%d\n", ans)) {for (read (m), tot=i=0;i<m;i++) {read (x); if (!vis[x=dfn[x]]) vis[a[++tot]=x]=1; } vis[a[++tot]=1]=1; M=tot,sort (A +1,A+M+1,CMP); for (i=1;i<m;i++) if (!vis[x=lca (a[i],a[i+1])) vis[a[++tot]=x]=1; M=tot,sort (A+1,A+M+1,CMP); for (ans=0,q[t=1]=a[1],i=2;i<=m;q[++t]=a[i++]) {while (st[a[i]]<st[q[t]]| | En[a[i]]>en[q[t]]) t--; Ans+=d[a[i]]-d[q[t]]; } for (i=1;i<=m;i++) vis[a[i]]=0; } return 0;}
BZOJ2851: Extreme Full Moon