[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)$
由于复杂度较高,可能需要卡一下常数
  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 }
View Code

 

posted @ 2020-07-31 08:12  PYWBKTDA  阅读(148)  评论(0编辑  收藏  举报