zoukankan      html  css  js  c++  java
  • CodeForces-631C Report 单调栈,思维

    CodeForces-631C Report 单调栈,思维

    题意

    给定一个初始序列(a)

    输出经过(m)次操作后的序列

    每个操作是两种之一

    • (1 quad r) ,将序列([1,r]) 从小到大排序
    • (2quad r) ,将序列([1,r])从大到小排序

    分析

    暴力显然是不可取的。

    注意到性质

    对于操作(i,j),若$i > j (且)r_i > r_j$ 那么这个(j)是无效的。

    这提示我们利用这个性质缩小范围。

    根据(r)维护一个单调递减的单调栈。每次我们只需要考虑两个相邻的栈的(r)之间的元素。

    并且由于之前最大的(r)已经把([1,r])排好序了。接下来每次都只是用双指针选出排好序中连续的一段。

    这样就可以(O(nlogn))实现,瓶颈在于排序。

    代码

    int a[200005];
    int b[200005];
    int c[200005];
    int op[200005];
    int st[200005];
    
    int main() {
        int n = readint();
        int m = readint();
        int ptr = 0;
        for (int i = 0; i < n; i++)
            a[i] = readint();
        for (int i = 0; i < m; i++) {
            int tmp = readint();
            c[i] = readint();
            while (ptr && c[st[ptr - 1]] < c[i])
                ptr--;
            st[ptr] = i, op[ptr++] = tmp;
        }
        int pos = c[st[0]];
        for (int i = 0; i < pos; i++)
            b[i] = a[i];
        sort(b, b + pos);
        int l = 0;
        int r = c[st[0]];
        for (int i = 1; i < ptr; i++) {
            for (int j = c[st[i - 1]]; j > c[st[i]]; j--)
                a[j - 1] = (op[i - 1] == 1) ? b[--r] : b[l++];
        }
        if (ptr - 1 >= 0) {
            for (int i = c[st[ptr - 1]]; i > 0; i--)
                a[i - 1] = (op[ptr - 1] == 1) ? b[--r] : b[l++];
        }
        for (int i = 0; i < n; i++)
            printf("%d ", a[i]);
    }
    
  • 相关阅读:
    一卦,测一年运气
    测一下我心中想的事
    一卦,测一下我心里想的事
    这一卦,学到了不少东西
    癸山丁向下卦(七运)
    起卦测我心里想的事
    现在的卦,越来越看不懂了
    luogu P2759 奇怪的函数 |二分答案
    luogu P2515 [HAOI2010]软件安装 |Tarjan+树上背包
    luogu P2343 宝石管理系统 |分块+堆
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13788431.html
Copyright © 2011-2022 走看看