社区讨论

求条,样例2输出40

P11307[COTS 2016] 建造费 Pristojba参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@mjzdp7xb
此快照首次捕获于
2026/01/04 14:56
2 个月前
此快照最后确认于
2026/01/04 15:35
2 个月前
查看原帖
将近 3h 了,有点崩
CPP
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f3f3f3fll
using namespace std;
namespace __Singularity{
	ll n,a[101000],m,l,r,x,bel[101000],Fa[101000],cnt,val[101000],to[101000],ans;
	vector<pair<ll,ll> >tu[101000];
	pair<ll,pair<ll,ll> >e[101000];
	struct node{ll dis1,dis2,col1,col2;}bian[101000];
	node operator+(node p,node q){
		pair<ll,ll>a[5];
		a[1]={p.dis1,p.col1};
		a[2]={q.dis1,q.col1};
		a[3]={p.dis2,p.col2};
		a[4]={q.dis2,q.col2};
		sort(a+1,a+1+4);
		node tmp;
		tmp.dis1=a[1].first,tmp.col1=a[1].second;
		if(a[2].second!=a[1].second){
			tmp.dis2=a[2].first,tmp.col2=a[2].second;
			return tmp;
		}
		if(a[3].second!=a[1].second){
			tmp.dis2=a[3].first,tmp.col2=a[3].second;
			return tmp;
		}
		if(a[4].second!=a[1].second){
			tmp.dis2=a[4].first,tmp.col2=a[4].second;
			return tmp;
		}
		tmp.dis2=inf,tmp.col2=0;
		return tmp;
	}
	ll find(ll lx){
		if(Fa[lx]==lx) return lx;
		return Fa[lx]=find(Fa[lx]);
	}
	struct TREE{
		struct tree{node res,tag;}tr[401000];
		void build(ll pl,ll pr,ll lx){
			tr[lx].tag={inf,inf,0,0};
			if(pl==pr){
				tr[lx].res={a[pl],inf,bel[pl],0};
				return;
			}
			ll pmid=(pl+pr)>>1;
			build(pl,pmid,lx*2);
			build(pmid+1,pr,lx*2+1);
			tr[lx].res=tr[lx*2].res+tr[lx*2+1].res;
		}
		void add(ll pl,ll pr,ll lx,ll al,ll ar,node av){
			if(al<=pl&&pr<=ar){
				tr[lx].tag=tr[lx].tag+av;
				return;
			}
			tr[lx*2].tag=tr[lx*2].res+tr[lx].tag;
			tr[lx*2+1].tag=tr[lx*2+1].res+tr[lx].tag;
			ll pmid=(pl+pr)>>1;
			if(al<=pmid) add(pl,pmid,lx*2,al,ar,av);
			if(pmid<ar) add(pmid+1,pr,lx*2+1,al,ar,av);
		}
		node query(ll pl,ll pr,ll lx,ll ql,ll qr){
			if(ql<=pl&&pr<=qr) return tr[lx].res;
			ll pmid=(pl+pr)>>1;
			if(ql<=pmid&&pmid<qr) return query(pl,pmid,lx*2,ql,qr)+query(pmid+1,pr,lx*2+1,ql,qr);
			else if(ql<=pmid) return query(pl,pmid,lx*2,ql,qr);
			else return query(pmid+1,pr,lx*2+1,ql,qr);
		}
		node query(ll pl,ll pr,ll lx,ll qk){
			if(pl==pr) return tr[lx].tag;
			tr[lx*2].tag=tr[lx*2].res+tr[lx].tag;
			tr[lx*2+1].tag=tr[lx*2+1].res+tr[lx].tag;
			ll pmid=(pl+pr)>>1;
			if(qk<=pmid) return query(pl,pmid,lx*2,qk);
			else return query(pmid+1,pr,lx*2+1,qk);
		}
	}TR;
	void Main(){
		cin>>n>>m;
		for(int i=1;i<=n;i++) cin>>a[i],Fa[i]=i;
		for(int i=1;i<=m;i++) cin>>x>>l>>r,tu[x].push_back({l,r});
		while(1){
			ll fl=1;
			for(int i=1;i<=n;i++) if(find(i)!=find(1)) fl=0;
			if(fl==1) break;
			for(int i=1;i<=n;i++) bel[i]=find(i),bian[i]={inf,inf,0,0},val[i]=inf,to[i]=0;
			TR.build(1,n,1);
			cnt=0;
			for(int i=1;i<=n;i++){
				node tmp={inf,inf,0,0};
				for(auto j:tu[i]){
					tmp=tmp+TR.query(1,n,1,j.first,j.second);
					TR.add(1,n,1,j.first,j.second,{a[i],inf,bel[i],0});
				}
				if(tmp.col1!=bel[i]&&tmp.col1!=0)
					if(val[bel[i]]>tmp.dis1+a[i])
						val[bel[i]]=tmp.dis1+a[i],to[bel[i]]=tmp.col1;
				if(tmp.col2!=bel[i]&&tmp.col2!=0)
					if(val[bel[i]]>tmp.dis2+a[i])
						val[bel[i]]=tmp.dis2+a[i],to[bel[i]]=tmp.col2;
			}
			for(int i=1;i<=n;i++){
				node tmp=TR.query(1,n,1,i);
				tmp.dis1+=a[i],tmp.dis2+=a[i];
				bian[bel[i]]=bian[bel[i]]+tmp;
			}
			for(int i=1;i<=n;i++)
				if(find(i)==i){
					if(bian[i].col1!=i&&bian[i].col1!=0)
						if(val[i]>bian[i].dis1)
							val[i]=bian[i].dis1,to[i]=bian[i].col1;
					if(bian[i].col2!=i&&bian[i].col2!=0)
						if(val[i]>bian[i].dis2)
							val[i]=bian[i].dis2,to[i]=bian[i].col2;
					e[++cnt]={val[i],{i,to[i]}};
				}
			sort(e+1,e+cnt+1);
			for(int i=1;i<=cnt;i++){
				ll fu=find(e[i].second.first),fv=find(e[i].second.second);
				if(fu!=fv) Fa[fu]=fv,ans+=e[i].first;
			}
		}
		cout<<ans;
	}
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	ll T=1;
//	cin>>T;
	while(T--) __Singularity::Main();
	return 0;
}

回复

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

正在加载回复...