He don't know, so he chases them away.

1-构造完全图(B)

2个半小时,只因为掉了一个语句就错了……


题意:对于完全图G,若有且仅有一棵最小生成树T,则称完全图G是由T拓展出的。给你一颗树T,找出T 能拓展出的边权和最小的完全图G。

想看并查集的可以去别的地方,我这只有线段树合并。(绝对不是因为我不会并查集解法)

复制代码
#include<bits/stdc++.h>
#define fst    first
#define snd    second
using namespace std;
typedef long long ll;
const int N=1e5+5,D=1e5;
int n,cnt;
ll ans;
vector<pair<int,int> > g[N];
struct segtree
{
    int l,r,num;
    ll sum;
    bool pl;
}node[N<<5];
inline void pushup(int o)
{
    node[o].num=node[node[o].l].num+node[node[o].r].num;
    node[o].sum=node[node[o].l].sum+node[node[o].r].sum;
}
inline void pushdown(int o)
{
    if(node[o].pl)
    {
        node[node[o].l].num=node[node[o].r].num=node[node[o].l].sum=node[node[o].r].sum=0;
        node[node[o].l].pl=node[node[o].r].pl=1;
    }
    node[o].pl=0;
}
void adate(int &o,int l,int r,int pos,int v)
{
    if(!o)    o=++cnt;
    pushdown(o);
    if(l==r)
    {
        node[o].num+=v;
        node[o].sum+=(ll)v*(ll)l;
        node[o].pl=0;
        return;
    }
    int mid=l+r>>1;
    if(pos<=mid)    adate(node[o].l,l,mid,pos,v);
    else    adate(node[o].r,mid+1,r,pos,v);
    pushup(o);
}
void segdate(int o,int l,int r,int pos)
{
    if(!o)    return;
    pushdown(o);
    if(r<=pos)
    {
        node[o].num=node[o].sum=0;
        node[o].pl=1;
        return;
    }
    int mid=l+r>>1;
    segdate(node[o].l,l,mid,pos);
    if(mid+1<=pos)    segdate(node[o].r,mid+1,r,pos);
    pushup(o);
}
int query(int o,int l,int r,int pos)
{
    if(!o)    return 0;
    pushdown(o);
    if(r<=pos)    return node[o].num;
    int mid=l+r>>1,ret=0;
    ret=query(node[o].l,l,mid,pos);
    if(mid+1<=pos)    ret+=query(node[o].r,mid+1,r,pos);
    return ret;
}
int Merge(int a,int b,int l,int r,ll &rsum,ll &lnum)
{
    pushdown(a);
    pushdown(b);
    if(!a)
    {
        rsum-=node[b].sum;
        lnum+=node[b].num;
        return b;
    }
    if(!b)
    {
        ans+=node[a].sum*lnum+rsum*(ll)node[a].num;
        return a;
    }
    if(l==r)
    {
        rsum-=node[b].sum;
        lnum+=node[b].num;
        ans+=node[a].sum*lnum+rsum*(ll)node[a].num;
        node[a].num+=node[b].num;
        node[a].sum+=node[b].sum;
        return a;
    }
    int mid=l+r>>1;
    node[a].l=Merge(node[a].l,node[b].l,l,mid,rsum,lnum);
    node[a].r=Merge(node[a].r,node[b].r,mid+1,r,rsum,lnum);
    pushup(a);
    return a;
}
void dfs(int x,int f)
{
    adate(x,0,D,0,1);
    for(auto v:g[x])
    {
        if(v.fst==f)    continue;
        dfs(v.fst,x);
        adate(v.fst,0,D,v.snd,query(v.fst,0,D,v.snd-1));
        segdate(v.fst,0,D,v.snd-1);
        ll lnum=0,rsum=node[v.fst].sum;
        Merge(x,v.fst,0,D,rsum,lnum);
    }
}
int main()
{
    freopen("gouzao.in","r",stdin);
    freopen("gouzao.out","w",stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(int i=1,a,b,v;i<n;++i)
    {
        cin>>a>>b>>v;
        g[a].push_back({b,v});
        g[b].push_back({a,v});
    }
    cnt=n;
    dfs(1,0);
    cout<<ans+((ll)(n-2)*(ll)(n-1)/2ll);
    return 0;
}
复制代码

 

posted @   eggome  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现

Some day yet, he'll begin his life again.

点击右上角即可分享
微信分享提示