[BZOJ4383][POI2015]Pustynia (拓扑排序)

题目要求构造一个满足特定条件的正整数序列,通过拓扑排序和线段树优化解决。给定序列长度、特殊数个数及若干信息,需要在满足信息条件下构造序列或判断无解。通过将信息转化为有向边,利用线段树减少边的数量,达到O(n + Klogn)复杂度,最终进行拓扑排序。
摘要由CSDN通过智能技术生成

题意:给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l]...a[r]里这k个数中的任意一个都比任意一个剩下的r-l+1-k个数大。任意构造出一组满足条件的方案,或者判断无解。n<=10w, m<=20w, k的和<=30w。

定义一条有向边(u,v,w)表示a[u]-w>=a[v],对于每条信息,枚举属于那k个数中的某个数i向每个不在那k个数当中的数连一条权值为1的边。跑拓扑排序DP,如果无环且合法则输出即可。但是这样连边边数是n^2的,会爆。

考虑vfk的a+b problem那套理论,由于连边的一定是一段连续的区间,我们用线段树优化构图。一开始线段树上父亲节点向儿子节点连权值为0的边,然后每次得到一条信息,抽象一个虚拟点,将K个点全部向这个虚拟点连权值为0的边。这K个点会将这个区间分成K+1段连续区间,我们对每一段连续区间在线段树上查询到logn段区间,然后虚拟点像这logn段区间连边即可。总共连的边数应该是O(n+Klogn)条,点数为O(n+m)。然后就可以跑拓扑排序了。实现的时候注意有很多细节,比如每个数的取值范围之类的。

#include<iostream>
#include<algorithm>
#include&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值