题目暴力做法是:
在m(m<=100)次循环内 分别对当前长度为n(n<=5e5)的数组sort一遍,大致取前k小(k<=100)。
我能想到的觉得比较优的做法是:在m次循环内,遍历数据并把符合大小的数据放进单调队列,保证单调队列的数据个数<=k,然后,不断判断新元素与队头元素的大小,更新答案。然而还是超时。
比赛题解是这么说的:
作者:Sovietqwq✨
链接:https://ac.nowcoder.com/discuss/342616?type=101&order=0&pos=1&page=1
来源:牛客网
对于当前区间l,rl,rl,r,随机选取一个元素costi, i∈[l,r]作为基准数base。然后维护两个指针,将区间中所有小于base的元素放到base的左边,大于base的元素放到base右边。这一步可以O(区间长度)完成。
设结束时两个指针(即base)在p位置。p左边元素都小于base,p右边的元素都大于base(可能等于,不影响答案)。那么我们统计p左边的元素个数t,如果t≥k就递归到区间[l,p];否则答案加上p左边的所有花费,k-=t,递归到区间[p+1,r]。
复杂度为T(n)=T(2n)+O(n)=O(n)。总复杂度O(nm)。
然后,这么做就不超时了!....
然后,还学习了一个东西:
可以很大随机数。
std::random_device rd; std::mt19937 mt(rd());//或者直接:std::mt19937 mt(time(0)); int main() { int a=mt()%mod; printf("%d",a); }