题意:给定一个长度为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&