jzoj5976

题意

给定\(n\)长度的序列\(\{a\}\)\(q\)次询问\((l,r,v)\),要求执行

if(l<r)
    for(int i=l;i<=r;++i) if(a[i]>v)
        swap(a[i],v);
else
{
    for(int i=l;i<=n;++i) if(a[i]>v)
        swap(a[i],v);
    for(int i=1;i<=r;++i) if(a[i]>v)
        swap(a[i],v);
}
return v;

做法

\(l=1,r=n\),我们实际上不需要这个序列的位置顺序了,每次都是最大值与\(v\)比较
故考虑分块,对整块与最大值比较,若需要替换则将其作为标记放入那个块
显然边角块是需要重构的,考虑将当前块的标记放入小根堆
然后从头到尾扫一遍,若当前位置大于堆顶,则将堆顶放在当前位置,将当前位置的值放入小根堆

正确性:
每个位置都会被所有标记经过,故直接选择最优的比较

posted @ 2020-06-02 22:18  Grice  阅读(121)  评论(0编辑  收藏  举报