【排序优化】牛客练习赛54D

牛客练习赛54D

题目暴力做法是:

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

猜你喜欢

转载自www.cnblogs.com/kkkek/p/11871649.html