求调,12pts,AC#12
查看原帖
求调,12pts,AC#12
1263684
Elysialr楼主2025/1/16 22:20
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf (1LL<<60)
#define SIZE 1000001
#define x_lc ((x<<1))
#define x_rc ((x<<1)|1)
#define x_mid ((t[x].l+t[x].r)>>1)
#define leng(x) (t[x].r-t[x].l+1)

struct road{
    ll ver,cost,id;
};
struct node{
    ll l,r;
    ll sum;
    ll maxn;
    ll minn;
    bool flag;
    void reverse(){
        flag^=1;
        swap(maxn,minn);
        maxn=-maxn;
        minn=-minn;
        sum=-sum;
    }
};
struct tree{
    node t[SIZE];
    void build(ll x,ll l,ll r){
        t[x].l=l;
        t[x].r=r;
        if(l==r) return;
        build(x_lc,l,x_mid);
        build(x_rc,x_mid+1,r);
    }
    void push(ll x){
        if(t[x].flag){
            t[x].flag=0;
            t[x_lc].reverse();
            t[x_rc].reverse();
        }
    }
    void update(ll x){
        t[x].maxn=max(t[x_lc].maxn,t[x_rc].maxn);
        t[x].minn=min(t[x_lc].minn,t[x_rc].minn);
        t[x].sum=t[x_lc].sum+t[x_rc].sum;
    }
    void change(ll x,ll a,ll b){
        if(t[x].l==t[x].r){
            t[x].maxn=b;
            t[x].minn=b;
            t[x].sum=b;
            return;
        }
        push(x);
        if(x_mid>=a) change(x_lc,a,b);
        if(x_mid+1<=a) change(x_rc,a,b);
        update(x);
    }
    void reverse(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r){
            t[x].reverse();
            return;
        }
        push(x);
        if(x_mid>=l) reverse(x_lc,l,r);
        if(x_mid+1<=r) reverse(x_rc,l,r);
        update(x);
    }
    ll query_max(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r) return t[x].maxn;
        ll res=-inf;
        push(x);
        if(x_mid>=l) res=max(res,query_max(x_lc,l,r));
        if(x_mid+1<=r) res=max(res,query_max(x_rc,l,r));
        return res;
    }
    ll query_min(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r) return t[x].minn;
        ll res=inf;
        push(x);
        if(x_mid>=l) res=min(res,query_min(x_lc,l,r));
        if(x_mid+1<=r) res=min(res,query_min(x_rc,l,r));
        return res;
    }
    ll query_sum(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r) return t[x].sum;
        ll res=0;
        push(x);
        if(x_mid>=l) res+=query_sum(x_lc,l,r);
        if(x_mid+1<=r) res+=query_sum(x_rc,l,r);
        return res;
    }
}SGT;

ll n,m,cnt;
ll to[SIZE];
ll fa[SIZE],d[SIZE];
ll son[SIZE],sz[SIZE];
ll id[SIZE],top[SIZE];
vector<road> r[SIZE];

void dfs1(ll x){
    sz[x]=1;
    for(ll i=0;i<r[x].size();i++){
        ll y=r[x][i].ver;
        ll z=r[x][i].cost;
        if(y==fa[x]) continue;
        fa[y]=x;
        d[y]=d[x]+1;
        dfs1(y);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]])
        son[x]=y;
    }
}
void dfs2(ll x,ll t){
    id[x]=++cnt;
    top[x]=t;
    if(son[x]==0) return;
    dfs2(son[x],t);
    for(ll i=0;i<r[x].size();i++){
        ll y=r[x][i].ver;
        ll z=r[x][i].cost;
        if(y==fa[x]) continue;
        SGT.change(1,id[y],z);
        to[r[x][i].id]=id[y];
        if(y==son[x]) continue;
        dfs2(y,y);
    }
}

void change(ll x,ll y){
    while(top[x]!=top[y]){
        if(d[top[x]]<d[top[y]]) swap(x,y);
        SGT.reverse(1,id[top[x]],id[x]);
        x=fa[top[x]];
    }
    if(d[x]>d[y]) swap(x,y);
    SGT.reverse(1,id[x]+1,id[y]);
}
ll query_max(ll x,ll y){
    ll res=-inf;
    while(top[x]!=top[y]){
        if(d[top[x]]<d[top[y]]) swap(x,y);
        res=max(res,SGT.query_max(1,id[top[x]],id[x]));
        x=fa[top[x]];
    }
    if(d[x]>d[y]) swap(x,y);
    res=max(res,SGT.query_max(1,id[x]+1,id[y]));
    return res;
}
ll query_min(ll x,ll y){
    ll res=inf;
    while(top[x]!=top[y]){
        if(d[top[x]]<d[top[y]]) swap(x,y);
        res=min(res,SGT.query_min(1,id[top[x]],id[x]));
        x=fa[top[x]];
    }
    if(d[x]>d[y]) swap(x,y);
    res=min(res,SGT.query_min(1,id[x]+1,id[y]));
    return res;
}
ll query_sum(ll x,ll y){
    ll res=0;
    while(top[x]!=top[y]){
        if(d[top[x]]<d[top[y]]) swap(x,y);
        res+=SGT.query_sum(1,id[top[x]],id[x]);
        x=fa[top[x]];
    }
    if(d[x]>d[y]) swap(x,y);
    res+=SGT.query_sum(1,id[x]+1,id[y]);
    return res;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);

    cin>>n;
    SGT.build(1,1,n);
    for(ll i=1;i<n;i++){
        ll x;road y;
        cin>>x>>y.ver>>y.cost;
        x++;y.ver++;
        y.id=i;
        r[x].push_back(y);
        swap(x,y.ver);
        r[x].push_back(y);
    }
    dfs1(1);
    dfs2(1,1);

    cin>>m;
    while(m--){
        string op;
        ll x,y;
        cin>>op>>x>>y;
        if(op=="C") SGT.change(1,to[x],y);
        x++;y++;
        if(op=="N") change(x,y);
        if(op=="SUM") cout<<query_sum(x,y)<<endl;
        if(op=="MAX") cout<<query_max(x,y)<<endl;
        if(op=="MIN") cout<<query_min(x,y)<<endl;
    }
    return 0;
}
2025/1/16 22:20
加载中...