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; }

浙公网安备 33010602011771号