求调,赏关
查看原帖
求调,赏关
1054181
longlinyu7楼主2024/1/25 16:46
#include<bits/stdc++.h>
using namespace std;
#define ll long long  
const int N=100005;
int n,m,u,v;
char opt;
vector<int>mp[N];
int fa[N],size[N],w[N],dep[N];
void dfs1(int u,int f){
    size[u]=1;
    fa[u]=f;
    dep[u]=dep[f]+1;
    for(int i=0;i<mp[u].size();i++){
        int v=mp[u][i];
        if(v==f)continue;
        dfs1(v,u);
        size[u]+=size[v];
        if(size[w[u]]<size[v])w[u]=v;   
    }
}
int vistime,dfn[N],rdfn[N],top[N];
void dfs2(int u,int T){
    top[u]=T;
    dfn[u]=++vistime;
    rdfn[vistime]=u;
    if(!w[u]){
        dfs2(w[u],T);
        for(int i=0;i<mp[u].size();i++){
            int v=mp[u][i];
            if((v!=fa[u])&&(v!=w[u])){
                dfs2(v,v);   //不是重孩子,连头是其自己
            }
        }
    }
}
int q[N*4],lzy[N*4];
void pushup(int u){   //
    q[u]=q[u*2]+q[u*2+1];
}
void build(int u,int L,int R){
    if(L==R){
        q[u]=0;
    }
    else{
        int M=(L+R)>>1;
        build(u*2,L,M);
        build(u*2+1,M+1,R);
        pushup(u);
    }
}
bool InRange(int L,int R,int l,int r){
    return (l<=L)&&(R<=r);
}
bool OutoRange(int L,int R,int l,int r){
    return (L>r)||(R<l);
}
void maketag(int u,int len,ll x){  //该标记
    lzy[u]+=x;
    q[u]+=len*x;
}
void pushdown(int u,int L,int R){  //传递标记
    int M=(L+R)>>1;
    maketag(u*2,M-L+1,lzy[u]);
    maketag(u*2+1,R-M,lzy[u]);
    lzy[u]=0;  
}
void update(int u,int L,int R,int l,int r,ll x){
    if(InRange(L,R,l,r)){  //包含直接加标记
        maketag(u,R-L+1,x);
    }
    else if(!OutoRange(L,R,l,r)){  //有交集需要先将标记传下去
    // cout<<2<<"\n";
        int M=(L+R)>>1;
        pushdown(u,L,R);
        update(u*2,L,M,l,r,x);
        update(u*2+1,M+1,R,l,r,x);
        pushup(u); //加起来
    }
}
ll query(int u,int L,int R,int l,int r){
    if(InRange(L,R,l,r)){
        return q[u];
    }
    else if(!OutoRange(L,R,l,r)){
        int M=(L+R)>>1;
        pushdown(u,L,R);
        return query(u*2,L,M,l,r)+query(u*2+1,M+1,R,l,r);
    }
    else return 0;
}
void update1(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        update(1,1,n,dfn[top[x]],dfn[x],1);
        x=fa[top[x]];
    }
    if(x!=y){
        update(1,1,n,min(dfn[x],dfn[y])+1,max(dfn[x],dfn[y]),1);
    }
}
ll query1(int x,int y){
    ll ans=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        ans+=query(1,1,n,dfn[top[x]],dfn[x]);
        x=fa[top[x]];
    }
    ans+=query(1,1,n,min(dfn[x],dfn[y])+1,max(dfn[x],dfn[y]));
    return ans;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<n;i++){
        cin>>u>>v;
        mp[u].push_back(v);
        mp[v].push_back(u);
    }
    dfs1(1,0);
    dfs2(1,0);
    build(1,1,n);
    while(m--){
        cin>>opt>>u>>v;
        if(opt=='P'){
            update1(u,v);
            // for(int i=1;i<=n;i++){
            //     for(int j=1;j<=n;j++){
            //     cout<<query1(i,j)<<" ";
            //     }
            //     cout<<"\n";
            // }
        }
        else {
            cout<<query1(u,v)<<"\n";
        }
    }
    
}
2024/1/25 16:46
加载中...