蒟蒻树剖玄关求条
查看原帖
蒟蒻树剖玄关求条
974911
rzt123楼主2024/7/29 20:30

rt

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ft first
#define sd second
#define PII pair<int,int>
#define fst ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
inline int read() {
    int x = 0, w = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = getchar();      }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = getchar(); }
    return x * w;
}
void write(int x) {
  static int sta[35];
  int top = 0;
  do {
    sta[top++] = x % 10, x /= 10;
  } while (x);
  while (top) putchar(sta[--top] + 48);  
}


const int INF=0x3f3f3f3f,MOD=1e9+7;
const int N=2e5+5;
int n; 
struct edge
{
    int v,w,id;
};
int a[N];
int b[N];
vector<edge> g[N];
int tot;
int fa[N];
int sz[N];
int dfn[N];
int rnk[N];
int son[N];
int top[N];
int dep[N];
void dfs1(int x)
{
    sz[x]=1;
    son[x]=-1;
    for(auto e: g[x])
    {
        int v=e.v;
        int w=e.w;
        if(fa[x]==v) continue;
        a[v]=w;
        b[e.id]=v;
        fa[v]=x;
        dep[v]=dep[x]+1;
        dfs1(v);
        sz[x]+=sz[v];
        if(son[x]==-1||sz[v]>sz[son[x]]) son[x]=v;
    }
}
void dfs2(int x,int t)
{
    top[x]=t;
    dfn[x]=++tot;
    rnk[tot]=x;
    if(son[x]!=-1) dfs2(son[x],t);
    for(auto e: g[x]) 
    {
        int v=e.v;
        if(v==fa[x]||v==son[x]) continue;
        dfs2(v,v);
    }
}

#define lson (rt<<1)
#define rson (rt<<1|1)
#define mid ((l+r)>>1)
struct Node
{
    int l,r,v=0,miv=INF,mxv=-INF;
    int lazy;
};
struct seg_tree
{
    Node tr[N<<2];
    void pushup(int rt)
    {
        tr[rt].v=tr[lson].v+tr[rson].v;
        tr[rt].miv=min(tr[lson].miv,tr[rson].miv);
        tr[rt].mxv=max(tr[lson].mxv,tr[rson].mxv);
    }
    void pushdown(int rt)
    {
        if(tr[rt].lazy)
        {
            tr[lson].v=-tr[lson].v;
            swap(tr[lson].mxv,tr[lson].miv);
            tr[lson].mxv=-tr[lson].mxv;
            tr[lson].miv=-tr[lson].miv;
            tr[lson].lazy^=1;
            tr[rson].v=-tr[rson].v;
            swap(tr[rson].mxv,tr[rson].miv);
            tr[rson].mxv=-tr[rson].mxv;
            tr[rson].miv=-tr[rson].miv;
            tr[rson].lazy^=1;
            tr[rt].lazy=0;
        }
    }
    void build(int rt,int l,int r)
    {
        tr[rt]={l,r,0,INF,-INF,0};
        if(l==r)
        {
            tr[rt].v=tr[rt].miv=tr[rt].mxv=a[rnk[l]];
            return ;
        }
        build(lson,l,mid);
        build(rson,mid+1,r);
        pushup(rt);
    }
    void update(int rt,int st,int ed)
    {
        int l=tr[rt].l,r=tr[rt].r;
        if(st<=l&&r<=ed) 
        {
            tr[rt].v=-tr[rt].v;
            swap(tr[rt].mxv,tr[rt].miv);
            tr[rt].mxv=-tr[rt].mxv;
            tr[rt].miv=-tr[rt].miv;
            tr[rt].lazy^=1;
            return ;
        }
        pushdown(rt);
        if(st<=mid) update(lson,st,ed);
        if(mid<ed) update(rson,st,ed);
        pushup(rt);
    }
    Node query(int rt,int st,int ed)
    {
        int l=tr[rt].l;
        int r=tr[rt].r;
        if(st<=l&&r<=ed)
        {
            return tr[rt];
        }
        pushdown(rt);
        if(ed<=mid)
            return query(lson,st,ed);
        if(mid<st)
            return query(rson,st,ed);
        Node L=query(lson,st,ed),R=query(rson,st,ed);
        Node res;
        res.v=L.v+R.v;
        res.mxv=max(L.mxv,R.mxv);
        res.miv=min(L.miv,R.miv);
        res.l=L.l;
        res.r=R.r;
        return res;
    }
    void print(int rt)
    {
        int l=tr[rt].l;
        int r=tr[rt].r;
        cout<<"root: "<<rt<<" ["<<tr[rt].l<<" , "<<tr[rt].r<<" ] "<<" min: "<<tr[rt].miv<<" max: "<<tr[rt].mxv<<" value: "<<tr[rt].v<<endl;
        if(l==r) 
        {
            return ;
        }
        print(lson);
        print(rson);
    }
    void update1(int rt,int x,int k)
    {
        int l=tr[rt].l;
        int r=tr[rt].r;
        if(l==r&&l==x)
        {
            tr[rt].v=tr[rt].miv=tr[rt].mxv=k;
            return ;
        }
        pushdown(rt);
        if(x<=mid) update1(lson,x,k);
        if(mid<x) update1(rson,x,k);
        pushup(rt);
    }
}seg_tree;

#undef lson 
#undef rson
#undef mid
void update_Path(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        seg_tree.update(1,dfn[top[x]],dfn[x]);
        x=fa[top[x]];
    }
    if(dep[x]<dep[y]) swap(x,y);
    seg_tree.update(1,dfn[y],dfn[x]);
}
Node query_Path(int x,int y)
{
    Node res;
    while(top[x]!=top[y])
    {
        // cout<<x<<' '<<y<<endl;
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        Node t=seg_tree.query(1,dfn[top[x]],dfn[x]);
        res.v+=t.v;
        res.miv=min(res.miv,t.miv);
        res.mxv=max(res.mxv,t.mxv);
        x=fa[top[x]];
    }
    if(dep[x]<dep[y]) swap(x,y);
    Node t=seg_tree.query(1,dfn[y],dfn[x]);
    res.v+=t.v;
    res.miv=min(res.miv,t.miv);
    res.mxv=max(res.mxv,t.mxv);
    // cout<<t.v<<" "<<t.miv<<" "<<t.mxv<<endl;
    return res;
}

int m;
signed main()
{
 	fst;
    // freopen("P1505_1.in","r",stdin);
    // freopen("P1505_1.ans","w",stdout);
	cin>>n;
    for(int i=1;i<n;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        g[u].push_back({v,w,i});
        g[v].push_back({u,w,i});
    }
    // for(int i=0;i<n;i++)
    // {
    //     for(auto e: g[i])
    //     {
    //         cout<<e.v<<" ";
    //     }
    //     cout<<endl;
    // }
    dfs1(0);
    dfs2(0,0);
    seg_tree.build(1,1,tot);
    // seg_tree.print(1);
    cin>>m;
    while(m--)
    {
        string op;
        cin>>op;
        if(op[0]=='C')
        {
            int x,w;
            cin>>x>>w;
            seg_tree.update1(1,dfn[b[x]],w);
        }
        else if(op[0]=='N')
        {
            int l,r;
            cin>>l>>r;
            update_Path(l,r);
        }
        else if(op[0]=='S')
        {
            int u,v;
            cin>>u>>v;
            cout<<query_Path(u,v).v<<endl;
        }
        else if(op[1]=='A')
        {
            int u,v;
            cin>>u>>v;;
            cout<<query_Path(u,v).mxv<<endl;
        }
        else{
            int u,v;
            cin>>u>>v;
            cout<<query_Path(u,v).miv<<endl;
        }
    }
	return 0;
}

码风不好勿喷

2024/7/29 20:30
加载中...