社区讨论

蒟蒻求助,样例第二个输出0

P4069[SDOI2016] 游戏参与者 4已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@lo8nks0j
此快照首次捕获于
2023/10/27 21:32
2 年前
此快照最后确认于
2023/10/27 21:32
2 年前
查看原帖
不知道为啥第一次修改后mn就变成0了
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,inf=123456789123456789;
int n,m,cnt,id[N],sum,dep[N],dis[N],re[N],f[N][30],top[N],t[N<<2],sz[N],mn[N],son[N],head[N],tot;
struct o{
    int ne,to,dis;
}e[N<<1];
inline void add(int x,int y,int k){
    e[++tot].ne=head[x];
    head[x]=tot;
    e[tot].to=y;
    e[tot].dis=k;
}
struct oo{
    int k,b;
}a[N];
inline int y(oo a,int x){
    return a.k*x+a.b;
}
inline void dfs1(int x,int fa){
    f[x][0]=fa;
    sz[x]=1;
    dep[x]=dep[fa]+1;
    for(int i=1;i<=log2(dep[x]);i++){
        f[x][i]=f[f[x][i-1]][i-1];
    }
    for(int i=head[x];i;i=e[i].ne){
        int to=e[i].to;
        if(to==fa)continue;
        dis[to]=dis[x]+e[i].dis;
        dfs1(to,x);
        sz[x]+=sz[to];
        if(sz[to]>sz[son[x]])son[x]=to;
    }
}
inline void dfs2(int x,int tp){
    top[x]=tp;
    id[x]=++sum;
    re[sum]=x;
    if(!son[x])return;
    dfs2(son[x],tp);
    for(int i=head[x];i;i=e[i].ne){
        int to=e[i].to;
        if(to==f[x][0]||to==son[x])continue;
        dfs2(to,to);
    }
}
inline int lca(int x,int y){
    if(dep[x]<dep[y])swap(x,y);
    while(dep[x]>dep[y]){
        x=f[x][(int)log2(dep[x]-dep[y])];
    }
    if(x==y)return x;
    for(int i=20;~i;i--){
        if(f[x][i]!=f[y][i]){
            x=f[x][i];
            y=f[y][i];
        }
    }
    return f[x][0];
}
inline void pushup(int x,int l,int r){
    int ll=dis[re[l]],rr=dis[re[r]];
    mn[x]=min(mn[x],min(mn[x<<1],mn[x<<1|1]));
    mn[x]=min(mn[x],min(y(a[t[x]],ll),y(a[t[x]],rr)));
}
inline void update(int x,int l,int r,int ql,int qr,int k){
    if(l>qr||r<ql)return;
    int mid=(l+r)>>1;
    if(l>=ql&&r<=qr){
        int ll=dis[re[l]],rr=dis[re[r]],mi=dis[re[mid]];
        if(y(a[k],mi)<y(a[t[x]],mi))swap(t[x],k);
        if(y(a[k],ll)<y(a[t[x]],ll))update(x<<1,l,mid,ql,qr,k);
        if(y(a[k],rr)<y(a[t[x]],rr))update(x<<1|1,mid+1,r,ql,qr,k);
        pushup(x,l,r);
        return;
    }
    update(x<<1,l,mid,ql,qr,k);
    update(x<<1|1,mid+1,r,ql,qr,k);
    pushup(x,l,r);
    return;
}
inline int ask(int x,int l,int r,int ql,int qr){
    if(l>qr||r<ql)return 3e18;
    if(l>=ql&&r<=qr){
        return mn[x];
    }
    int mid=(l+r)>>1;
    int ans=min(y(a[t[x]],dis[re[max(l,ql)]]),y(a[t[x]],dis[re[min(r,qr)]]));
    ans=min(ans,min(ask(x<<1,l,mid,ql,qr),ask(x<<1|1,mid+1,r,ql,qr)));
    return ans;
}
inline void change(int x,int y,int k){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        update(1,1,n,id[top[x]],id[x],k);
        x=f[top[x]][0];
    }
    if(id[x]>id[y])swap(x,y);
    update(1,1,n,id[x],id[y],k);
    return;
}
inline int query(int x,int y){
    int ans=inf;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        ans=min(ans,ask(1,1,n,id[top[x]],id[x]));
        x=f[top[x]][0];
    }
    if(id[x]>id[y])swap(x,y);
    ans=min(ans,ask(1,1,n,id[x],id[y]));
    return ans;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    memset(mn,0x3f,sizeof(mn));
    for(int i=1;i<n;i++){
        int u,v,w;
        cin>>u>>v>>w;
        add(u,v,w);
        add(v,u,w);
    }
    dfs1(1,0);
    dfs2(1,1);
    for(int i=1;i<=m;i++){
        int op,s,t;
        cin>>op>>s>>t;
        if(op==1){
            int k,b;
            cin>>k>>b;
            int fa=lca(s,t);
            a[++cnt]=(oo){-k,k*dis[s]+b};
            change(s,fa,cnt);
            a[++cnt]=(oo){k,k*dis[s]-2*k*dis[fa]+b};
            change(fa,t,cnt);
        }else cout<<query(s,t)<<'\n';
    }
    return 0;
}

回复

7 条回复,欢迎继续交流。

正在加载回复...