[nowcoder5671D]Data structure
问题相当于统计$且\sum_{l\le x<y\le r且lca(x,y)=x}1=c(sz[x],2)-\sum_{son}c(sz[son],2)$,考虑用莫队来维护区间,那么相当于要支持:1.某个点到根的链修改;2.询问某个点的上述式子
树链剖分维护:对于轻儿子,将这个权值加入父亲,复杂度$o(n\sqrt{n}\log n)$;对于重儿子,由于只有单点,用可持久化线段树来维护,复杂度$o(n\log n)$
由于复杂度较高,可能需要卡一下常数
View Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200005 4 #define K 450 5 #define ll long long 6 #define L (k<<1) 7 #define R (L+1) 8 #define mid (l+r>>1) 9 struct ji{ 10 int nex,to; 11 }edge[N<<1]; 12 struct qu{ 13 int x,y,z,id; 14 }q[N]; 15 int E,V,n,m,r,x,y,head[N],fa[N],sz[N],mx[N],id[N],top[N],ro[N],f[N*20],ls[N*20],rs[N*20]; 16 ll sum[N],ans[N]; 17 bool cmp(qu x,qu y){ 18 return (x.x/K<y.x/K)||(x.x/K==y.x/K)&&(x.y<y.y); 19 } 20 ll c(int k){ 21 return (k-1LL)*k/2; 22 } 23 void add(int x,int y){ 24 edge[E].nex=head[x]; 25 edge[E].to=y; 26 head[x]=E++; 27 } 28 void dfs1(int k,int f){ 29 fa[k]=f; 30 sz[k]=1; 31 for(int i=head[k];i!=-1;i=edge[i].nex) 32 if (edge[i].to!=f){ 33 dfs1(edge[i].to,k); 34 sz[k]+=sz[edge[i].to]; 35 if (sz[mx[k]]<sz[edge[i].to])mx[k]=edge[i].to; 36 } 37 } 38 void dfs2(int k,int t){ 39 id[k]=++x; 40 top[k]=t; 41 if (mx[k])dfs2(mx[k],t); 42 for(int i=head[k];i!=-1;i=edge[i].nex) 43 if ((edge[i].to!=fa[k])&&(edge[i].to!=mx[k]))dfs2(edge[i].to,edge[i].to); 44 } 45 void update(int &k,int l,int r,int x){ 46 f[++V]=f[k]+1; 47 ls[V]=ls[k]; 48 rs[V]=rs[k]; 49 k=V; 50 if (l==r)return; 51 if (x<=mid)update(ls[k],l,mid,x); 52 else update(rs[k],mid+1,r,x); 53 } 54 int query(int k,int l,int r,int x,int y){ 55 if ((!k)||(l>y)||(x>r))return 0; 56 if ((x<=l)&&(r<=y))return f[k]; 57 return query(ls[k],l,mid,x,y)+query(rs[k],mid+1,r,x,y); 58 } 59 ll query(int k,int l,int r){ 60 return c(query(ro[r],1,n,id[k],id[k]+sz[k]-1)-query(ro[l-1],1,n,id[k],id[k]+sz[k]-1)); 61 } 62 void update(int k,int x){ 63 while (k){ 64 k=top[k]; 65 if (k!=r){ 66 f[k]+=x; 67 sum[fa[k]]+=c(f[k])-c(f[k]-x); 68 } 69 k=fa[k]; 70 } 71 } 72 int main(){ 73 scanf("%d%d%d",&n,&m,&r); 74 memset(head,-1,sizeof(head)); 75 for(int i=1;i<n;i++){ 76 scanf("%d%d",&x,&y); 77 add(x,y); 78 add(y,x); 79 } 80 x=0; 81 dfs1(r,0); 82 dfs2(r,r); 83 for(int i=1;i<=m;i++){ 84 scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].z); 85 q[i].id=i; 86 } 87 sort(q+1,q+m+1,cmp); 88 for(int i=1;i<=n;i++){ 89 ro[i]=ro[i-1]; 90 update(ro[i],1,n,id[i]); 91 } 92 for(int i=1;i<=m;i++) 93 if (q[i].x<=q[i].y)ans[q[i].id]=query(q[i].z,q[i].x,q[i].y)-query(mx[q[i].z],q[i].x,q[i].y); 94 memset(f,0,sizeof(f)); 95 x=1,y=0; 96 for(int i=1;i<=m;i++){ 97 if (q[i].x>q[i].y)continue; 98 while (q[i].x<x)update(--x,1); 99 while (y<q[i].y)update(++y,1); 100 while (x<q[i].x)update(x++,-1); 101 while (q[i].y<y)update(y--,-1); 102 ans[q[i].id]-=sum[q[i].z]; 103 } 104 for(int i=1;i<=m;i++)printf("%lld\n",ans[i]); 105 }