analysis
We consider it DFS processing sequence, then obviously, when the two points can not elect not to ancestral relationship, which does not have the legal number of paths in the subtree size product
We call this a two-dimensional plane of the abstract, is the greatest sequence DFS DFS sequence and a point in the subtree as wide, as another similar long rectangular area
We have put all the points on the plane, the total area is the number of illegal schemes, can be treated with the scan line segment tree +
Ancestral relationships is similar, except ancestor son comprising subtrees can not be selected, it is [1, l [son] -1] [r [son] + 1, n] of the two bounding rectangle
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N=1e5+10; struct Line { int x,l,r,c; }h[4*N]; int lcnt; struct Graph { int v,nx; }g[2*N]; int cnt,list[N],l[N],r[N],tme,f[N][20],dep[N],t[4*N],v[4*N]; int n,m; long long ans; void Add(int u,int v) { g[++cnt]=(Graph){v,list[u]};list[u]=cnt; g[++cnt]=(Graph){u,list[v]};list[v]=cnt; } void Addline(int x0,int x1,int y0,int y1) { h[++lcnt]=(Line){x0,y0,y1,1};h[++lcnt]=(Line){x1+1,y0,y1,-1}; } void DFS(int u,int fa) { f[u][0]=fa;l[u]=++tme;dep[u]=dep[fa]+1; for (int i=list[u];i;i=g[i].nx) if (g[i].v!=fa) DFS(g[i].v,u); r[u]=tme; } int LCA(int a,int b) { if (dep[a]<dep[b]) swap(a,b); for (int i=19;i>=0;i--) if (dep[f[a][i]]>=dep[b]) a=f[a][i]; if (a==b) return a; for (int i=19;i>=0;i--) if (f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i]; return f[a][0]; } bool CMP(Line a,Line b) { return a.x<b.x; } void Change(int x,int l,int r,int ll,int rr,int c) { if (r<l||rr<l||r<ll) return; if (ll<=l&&r<=rr) { t[x]+=c; if (t[x]) v[x]=r-l+1; else if (l!=r) v[x]=v[x<<1]+v[(x<<1)+1]; else v[x]=0; return; } int mid=l+r>>1; if (ll<=mid) Change(x<<1,l,mid,ll,rr,c); if (mid<rr) Change((x<<1)+1,mid+1,r,ll,rr,c); v[x]=t[x]?r-l+1:v[x<<1]+v[(x<<1)+1]; } int main() { freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); scanf("%d%d",&n,&m); for (int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),Add(u,v); DFS(1,0); for (int i=1;i<20;i++) for (int j=1;j<=n;j++) f[j][i]=f[f[j][i-1]][i-1]; for (int i=1,x,y;i<=m;i++) { scanf("%d%d",&x,&y); if (l[x]>l[y]) swap(x,y); int lca=LCA(x,y); if (lca==x) { int s=y; for (int i=19;i>=0;i--) if (dep[f[s][i]]>dep[x]) s=f[s][i]; if (l[s]-1>0) Addline(1,l[s]-1,l[y],r[y]); if (r[s]+1<=n) Addline(l[y],r[y],r[s]+1,n); } else Addline(l[x],r[x],l[y],r[y]); } sort(h+1,h+lcnt+1,CMP); for (int i=1,j=1;i<=n;i++) { while (h[j].x==i&&j<=lcnt) Change(1,1,n,h[j].l,h[j].r,h[j].c),j++; ans+=v[1]; } printf("%lld\n",1ll*n*(n-1ll)/2ll-ans); }