萌新刚学树剖 8 pts 求条
查看原帖
萌新刚学树剖 8 pts 求条
338144
tkth楼主2023/10/26 10:36
#include <iostream>
#define int long long
#define ls (x<<1)
#define rs (x<<1|1)
const int M = 2e5+10;
int n,m;
struct EDGE
{
    int Head[M],Next[M<<1],Ver[M<<1],Edge[M<<1],tot;
    inline void add(int x,int y,int z)
    {
        Ver[++tot]=y,Edge[tot]=z,Next[tot]=Head[x],Head[x]=tot;
    }
}E,E_;
int st[M],en[M],dis[M];
int dfn[M],rnk[M],top[M],fa[M],dep[M],siz[M],son[M],tot;
namespace Seg
{
    struct Tree
    {
        int l,r,num,max,min,sum,tag;
    }t[M<<2];
    inline void pushUp(int x)
    {
        t[x].sum=t[ls].sum+t[rs].sum;
        t[x].max=std::max(t[ls].max,t[rs].max);
        t[x].min=std::min(t[ls].min,t[rs].min);
        return ;
    }
    inline void pushDown(int x)
    {
        if(t[x].tag){
            t[ls].sum=-t[ls].sum;
            t[ls].num=-t[ls].num;
            std::swap(t[ls].max,t[ls].min);
            t[ls].min=-t[ls].min;
            t[ls].max=-t[ls].max;
            t[ls].tag^=1;

            t[rs].sum=-t[rs].sum;
            t[rs].num=-t[rs].num;
            std::swap(t[rs].max,t[rs].min);
            t[rs].min=-t[rs].min;
            t[rs].max=-t[rs].max;
            t[rs].tag^=1;

            t[x].tag=0;
        }
    }
    void build(int x,int l,int r)
    {
        t[x].l=l,t[x].r=r;
        if(l==r){
            t[x].num=t[x].sum=t[x].min=t[x].max=dis[rnk[l]];
            return ;
        }
        int mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushUp(x);
        return ;
    }
    void update_da(int x,int l,int r,int num)
    {
        if(t[x].l >= l&&t[x].r <= r){
            t[x].num=t[x].sum=t[x].min=t[x].max=num;
            return;
        }
        int mid=(t[x].l+t[x].r)>>1;
        if(mid >= l) update_da(ls,l,r,num);
        if(mid < r) update_da(rs,l,r,num);
        pushUp(x);
        return ;
    }
    void update_qu(int x,int l,int r)     
    {                                             
        if(t[x].l >= l&&t[x].r <= r){
            t[x].sum=-t[x].sum;
            t[x].num=-t[x].num;
            std::swap(t[x].max,t[x].min);
            t[x].min=-t[x].min;
            t[x].max=-t[x].max;
            t[x].tag^=1;
            return;
        }
        pushDown(x);
        int mid=(t[x].l+t[x].r)>>1;
        if(mid >= l) update_qu(ls,l,r);
        if(mid < r) update_qu(rs,l,r);
        pushUp(x);
        return ;
    }
    int getNum(int x,int l,int r,int mod)
    {
        if(t[x].l >= l&&t[x].r <= r){
            if(mod==1)return t[x].sum;
            if(mod==2)return t[x].min;
            if(mod==3)return t[x].max;
        }
        pushDown(x);
        int mid=(t[x].l+t[x].r)>>1,ans;
        if(mod==1){
            ans=0;
            if(mid >= l) ans+=getNum(ls,l,r,mod);
            if(mid < r) ans+=getNum(rs,l,r,mod);
        }
        if(mod==2){
            ans=0x3f3f3f3f3f3f3f;
            if(mid >= l) ans=std::min(ans,getNum(ls,l,r,mod));
            if(mid < r) ans=std::min(ans,getNum(rs,l,r,mod));
        }
        if(mod==3){
            ans=-0x3f3f3f3f3f3f3f;
            if(mid >= l) ans=std::max(ans,getNum(ls,l,r,mod));
            if(mid < r) ans=std::max(ans,getNum(rs,l,r,mod));
        }
        return ans;
    }
} 
void dfs1(int x,int f)
{
    son[x]=-1;
    siz[x]=1;
    for(int i = E.Head[x];i;i=E.Next[i]){
        int y=E.Ver[i],z=E.Edge[i];
        if(y==f) continue;
        fa[y]=x;
        dep[y]=dep[x]+1;
        dis[y]=z;
        dfs1(y,x);
        siz[x]+=siz[y];
        if(son[x]==-1||siz[son[x]]<siz[y])son[x]=y;
    }
}
void dfs2(int x,int t)
{
    top[x]=t;
    dfn[x]=++tot;
    rnk[tot]=x;
    if(son[x]==-1)return;
    dfs2(son[x],t);
    for(int i = E.Head[x];i;i=E.Next[i]){
        int y=E.Ver[i];
        if(y==fa[x]||y==son[x])continue;
        dfs2(y,y);
    }
}
inline void pathUpdate(int x,int y)
{
    if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
        Seg::update_qu(1,dfn[top[x]],dfn[x]);
        x=fa[top[x]];
    }
    if(x!=y){
        if(dep[x]>dep[y]) std::swap(x,y);
        Seg::update_qu(1,dfn[x]+1,dfn[y]);    
    }
    return;
}
inline int path(int x,int y,int mod)
{
    int ans;
    if(mod==1) ans=0;
    if(mod==2) ans=0x3f3f3f3f3f3f3f;
    if(mod==3) ans=-0x3f3f3f3f3f3f3f;
    if(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
        if(mod==1) ans+=Seg::getNum(1,dfn[top[x]],dfn[x],mod);
        if(mod==2) ans=std::min(Seg::getNum(1,dfn[top[x]],dfn[x],mod),ans);
        if(mod==3) ans=std::max(Seg::getNum(1,dfn[top[x]],dfn[x],mod),ans);
        x=fa[top[x]];
    }
    if(x!=y){
        if(dep[x]>dep[y]) std::swap(x,y);
        if(mod==1) ans+=Seg::getNum(1,dfn[x]+1,dfn[y],mod);
        if(mod==2) ans=std::min(Seg::getNum(1,dfn[x]+1,dfn[y],mod),ans);
        if(mod==3) ans=std::max(Seg::getNum(1,dfn[x]+1,dfn[y],mod),ans);
    }
    return ans;
}
inline int read(){
    int num=0,fl=1;char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') fl=-1;
        c=getchar();
    }
    while(c >='0'&&c <='9'){
        num=(num<<3)+(num<<1)+(c^48);
        c=getchar();
    }
    return num*fl;
}
signed main(){
    n=read();
    for(int i = 1;i < n;i++){
        int x=read(),y=read(),z=read();
        st[i]=x;en[i]=y;
        E.add(x,y,z),E.add(y,x,z);
    }
    dfs1(0,-1);
    dfs2(0,0);
    Seg::build(1,1,n);
    m=read();
    while(m--){
        char s[4];
        scanf("%s",s+1);
        if(s[1]=='S'){
            int x=read(),y=read();
            printf("%lld\n",path(x,y,1));
        }
        else if(s[2]=='I'){
            int x=read(),y=read();
            printf("%lld\n",path(x,y,2));
        }
        else if(s[2]=='A'){
            int x=read(),y=read();
            printf("%lld\n",path(x,y,3));
        }
        else if(s[1]=='C'){
            int i=read(),num=read();
            int x;
            if(dep[en[i]]>dep[st[i]]) x=en[i];
            else x=st[i];
            Seg::update_da(1,dfn[x],dfn[x],num);
        }
        else if(s[1]=='N'){
            int x=read(),y=read();
            pathUpdate(x,y);
        }
    }
    return 0;  
}

WA on #11

2023/10/26 10:36
加载中...