树剖8分只过#11求调
查看原帖
树剖8分只过#11求调
759015
awa2333楼主2022/11/14 13:03
#include <iostream>
#include <iomanip>

using namespace std;

using ll=long long;
constexpr int maxn=200010;

int n,m;
int datas[maxn],u[maxn],v[maxn];
int to[2*maxn],nxt[2*maxn],w[2*maxn],head[2*maxn],counte;
int siz[maxn],fa[maxn],son[maxn],top[maxn],dep[maxn],dfn[maxn],rnk[maxn],cnt;

void add(int u,int v,int ww){
    ++counte;
    to[counte]=v;
    w[counte]=ww;
    nxt[counte]=head[u];
    head[u]=counte;
}

void dfs1(int x){
    son[x]=0;
    siz[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(!dep[y]){
            datas[y]=w[i];
            dep[y]=dep[x]+1;
            fa[y]=x;
            dfs1(y);
            siz[x]+=siz[y];
            if(son[x]==0||siz[y]>siz[son[x]]){
                son[x]=y;
            }
        }
    }
}
void dfs2(int x,int t){
    top[x]=t;
    ++cnt;
    dfn[x]=cnt;
    rnk[cnt]=x;
    if(son[x]==0){
        return;
    }
    dfs2(son[x],t);
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y!=son[x]&&y!=fa[x]){
            dfs2(y,y);
        }
    }
}
int lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]){
            y=fa[top[y]];
        }else{
            x=fa[top[x]];
        }
    }
    if(dep[x]<dep[y]){
        return x;
    }else{
        return y;
    }
}

struct node{
    int l,r;
    ll max,min,sum,lazy;
};
int parent(int i){
    return i/2;
}
int left(int i){
    return i*2;
}
int right(int i){
    return i*2+1;
}
node tree[4*maxn];
void update(int i){
    tree[i].min=min(tree[left(i)].min,tree[right(i)].min);
    tree[i].max=max(tree[left(i)].max,tree[right(i)].max);
    tree[i].sum=(tree[left(i)].sum+tree[right(i)].sum);
}
void build(int i,int l,int r){
    tree[i].l=l;
    tree[i].r=r;
    if(l==r){
        tree[i].min=datas[l];
        tree[i].max=datas[l];
        tree[i].sum=datas[l];
        return;
    }
    int mid=(l+r)/2;
    build(left(i),l,mid);
    build(right(i),mid+1,r);
    update(i);
}
void pd_impl(int i){
    tree[i].lazy^=1;
    int t=tree[i].max;
    tree[i].max=-tree[i].min;
    tree[i].min=-t;
    tree[i].sum*=-1;
}
void pushdown(int i){
    if(tree[i].lazy==0){
        return;
    }
    pd_impl(left(i));
    pd_impl(right(i));
    tree[i].lazy^=1;
}
void change(int i,int p,int k){
    if(tree[i].l==tree[i].r){
        tree[i].sum=k;
        tree[i].min=k;
        tree[i].max=k;
        return;
    }
    if(tree[i].lazy){
        pushdown(i);
    }
    int mid=(tree[i].l+tree[i].r)/2;
    if(p<=mid){
        change(left(i),p,k);
    }else{
        change(right(i),p,k);
    }
    update(i);
}
void neg(int i,int l,int r){
    if(tree[i].r<=r&&tree[i].l>=l){
        tree[i].lazy^=1;
        tree[i].sum=-tree[i].sum;
        tree[i].min=-tree[i].min;
        tree[i].max=-tree[i].max;
        swap(tree[i].min,tree[i].max);
        return;
    }
    if(tree[i].lazy){
        pushdown(i);
    }
    if(tree[left(i)].r>=l){
        neg(left(i),l,r);
    }
    if(tree[right(i)].l<=r){
        neg(right(i),l,r);
    }
    update(i);
}
ll sum(int i,int l,int r){
    ll t{};
    if(tree[i].r<=r&&tree[i].l>=l){
        return tree[i].sum;
    }
    if(tree[i].lazy!=0){
        pushdown(i);
    }
    if(tree[left(i)].r>=l){
        t+=sum(left(i),l,r);
    }
    if(tree[right(i)].l<=r){
        t+=sum(right(i),l,r);
    }
    return t;
}
ll min(int i,int l,int r){
    ll t{1000000};
    if(tree[i].r<=r&&tree[i].l>=l){
        return tree[i].min;
    }
    if(tree[i].lazy!=0){
        pushdown(i);
    }
    if(tree[left(i)].r>=l){
        t=min(t,min(left(i),l,r));
    }
    if(tree[right(i)].l<=r){
        t=min(t,min(right(i),l,r));
    }
    return t;
}
ll max(int i,int l,int r){
    ll t{-1000000};
    if(tree[i].r<=r&&tree[i].l>=l){
        return tree[i].max;
    }
    if(tree[i].lazy!=0){
        pushdown(i);
    }
    if(tree[left(i)].r>=l){
        t=max(t,max(left(i),l,r));
    }
    if(tree[right(i)].l<=r){
        t=max(t,max(right(i),l,r));
    }
    return t;
}

int main(){
    cin>>n;
    for(int i=1;i<=n-1;++i){
        int u,v,w;
        cin>>u>>v>>w;
        ++u;
        ++v;
        ::u[i]=u;
        ::v[i]=v;
        add(u,v,w);
        add(v,u,w);
    }
    dep[1]=1;
    dfs1(1);
    dfs2(1,1);
    build(1,1,n);
    cin>>m;
    string op;
    for(int i=1;i<=m;++i){
        // clog<<i<<" ";
        int x,y;
        cin>>op>>x>>y;
        ++x;
        ++y;
        if(op=="C"){
            // clog<<"C";
            --y;
            --x;
            if(fa[u[x]]==v[x]){
                change(1,dfn[u[x]],y);
            }else{
                change(1,dfn[v[x]],y);
            }
        }else if(op=="N"){
            // clog<<"N";
            neg(1,x,y);
        }else if(op=="MAX"){
            // clog<<"MAX";
            ll l=-1000000,r=-1000000;
            int p=lca(x,y);
            while(x&&top[x]!=p){
                l=max(l,max(1,dfn[top[x]],dfn[x]));
                x=fa[top[x]];
            }
            if(x&&x!=p){
                l=max(l,max(1,dfn[son[p]],dfn[x]));
            }
            while(y&&top[y]!=p){
                r=max(r,max(1,dfn[top[y]],dfn[y]));
                y=fa[top[y]];
            }
            if(y&&y!=p){
                r=max(r,max(1,dfn[son[p]],dfn[y]));
            }
            cout<<max(l,r)<<"\n";
        }else if(op=="MIN"){
            // clog<<"MIN";
            ll l=1000000,r=1000000;
            int p=lca(x,y);
            while(x&&top[x]!=p){
                l=min(l,min(1,dfn[top[x]],dfn[x]));
                x=fa[top[x]];
            }
            if(x&&x!=p){
                l=min(l,min(1,dfn[son[p]],dfn[x]));
            }
            while(y&&top[y]!=p){
                r=min(r,min(1,dfn[top[y]],dfn[y]));
                y=fa[top[y]];
            }
            if(y&&y!=p){
                r=min(r,min(1,dfn[son[p]],dfn[y]));
            }
            cout<<min(l,r)<<"\n";
        }else{
            ll ans=0;
            int p=lca(x,y);
            while(x&&top[x]!=p){
                ans+=sum(1,dfn[top[x]],dfn[x]);
                x=fa[top[x]];
            }
            // clog<<"SUM ";
            if(x&&x!=p){
                ans+=sum(1,dfn[son[p]],dfn[x]);
            }
            while(y&&top[y]!=p){
                ans+=sum(1,dfn[top[y]],dfn[y]);
                y=fa[top[y]];
            }
            if(y&&y!=p){
                ans+=sum(1,dfn[son[p]],dfn[y]);
            }
            cout<<ans<<"\n";
        }
        // clog<<endl;
    }
}

检查好久了也没找出问题,求大佬指点

2022/11/14 13:03
加载中...