zoukankan      html  css  js  c++  java
  • [nowcoder5671D]Data structure

    问题相当于统计$且sum_{lle x<yle r且lca(x,y)=x}1=c(sz[x],2)-sum_{son}c(sz[son],2)$,考虑用莫队来维护区间,那么相当于要支持:1.某个点到根的链修改;2.询问某个点的上述式子
    树链剖分维护:对于轻儿子,将这个权值加入父亲,复杂度$o(nsqrt{n}log n)$;对于重儿子,由于只有单点,用可持久化线段树来维护,复杂度$o(nlog 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
    ",ans[i]);
    105 }
    View Code
  • 相关阅读:
    day 08 小结
    day 07作业
    逆向---入坑记
    Codeforces Round #523 (Div. 2) B,D
    VIM一键配置
    zoj 2704 Brackets 用栈维护括号匹配 (8-A)
    zoj 2840 File Searching
    zoj 1698 Easier Done Than Said?
    13暑假集训6 总结
    13暑假集训#7 总结
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13407673.html
Copyright © 2011-2022 走看看