树剖31pts求调

P3038 [USACO11DEC] Grass Planting G

Mr_Ender @ 2022-07-14 21:58:01


#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,fa[100005],d[100005],s[100005],son[100005],top[100005],w[100005],pos,tree[400005],lz[400005];
vector <int> edge[100005];
char op;
void dfs1(int f,int x){
    fa[x]=f;
    d[x]=d[f]+1;
    s[x]=1;
    for(int i=0;i<edge[x].size();i++){
        if(edge[x][i]!=f){
            dfs1(x,edge[x][i]);
            s[x]+=s[edge[x][i]];
            if(s[edge[x][i]]>s[son[x]]){
                son[x]=edge[x][i];
            }
        }
    }
    return;
}
void dfs2(int x,int topv){
    top[x]=topv;
    pos++;
    w[x]=pos;
    if(son[x]!=0){
        dfs2(son[x],topv);
    }
    for(int i=0;i<edge[x].size();i++){
        if(edge[x][i]!=fa[x]&&edge[x][i]!=son[x]){
            dfs2(edge[x][i],edge[x][i]);
        }
    }
}
void pushdown(int u,int l,int r){
    int mid=(l+r)/2;
    lz[u*2]+=lz[u];
    lz[u*2+1]+=lz[u];
    tree[u*2]+=(mid-l+1)*lz[u];
    tree[u*2+1]+=(r-mid)*lz[u];
    lz[u]=0;
    return;
}
void pushup(int u){
    tree[u]=tree[u*2]+tree[u*2+1];
    return;
}
void update(int u,int l,int r,int a,int b){
    if(l>b||r<a){
        return;
    }
    if(a<=l&&r<=b){
        lz[u]+=1;
        tree[u]+=r-l+1;
        return;
    }
    pushdown(u,l,r);
    int mid=(l+r)/2;
    update(u*2,l,mid,a,b);
    update(u*2+1,mid+1,r,a,b);
    pushup(u);
    return;
}
void add(int u,int v){
    while(top[u]!=top[v]){
        if(d[top[u]]<d[top[v]]){
            swap(u,v);
        }
        update(1,1,n,w[top[u]],w[u]);
        u=fa[top[u]];
    }
    if(u==v){
        return;
    }
    if(d[u]>d[v]){
        swap(u,v);
    }
    update(1,1,n,w[son[u]],w[v]);
}
int query(int u,int l,int r,int tar){
    if(l==r&&l==tar){
        return tree[u];
    }
    if(l>tar||r<tar){
        return 0;
    }
    int mid=(l+r)/2;
    return query(u*2,l,mid,tar)+query(u*2+1,mid+1,r,tar);
}
int main(){
    cin>>n>>m;
    for(int i=1;i<n;i++){
        cin>>u>>v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs1(0,1);
    dfs2(1,1);
    for(int i=1;i<=m;i++){
        cin>>op>>u>>v;
        if(op=='P'){
            add(u,v);
        }
        else{
            if(d[u]>d[v]){
                swap(u,v);
            }
            cout<<query(1,1,n,w[v])<<'\n';
        }
    }
    return 0;
}

|