• CF1558F Strange Sort 题解


    洛谷题解总结到位“这种排序题通常情况下要转换成 ( ext{01}) 序列处理”。设 (b_i=[a_ige x]),枚举所有的 (x),每次计算让所有 (0) 在最左边的最少轮数,取 (max) 就是答案。设 (f_i) 为前 (i)(0) 归位的最少论述。第 (i)(0) 会被前面一个卡住,因此 (f_ige f_{i-1}+1)。如果不被卡住,那么答案是 (cnt_i+[pos_i\%2=1])。其中 (cnt_i) 是第 (i)(0) 之前 (1) 的数量,(pos_i) 是第 (i)(0) 的位置。综上两种情况,有 (f_i=max(f_{i-1}+1,cnt_i+[pos_i\%2=1]))

    但我们只需要知道 (f_m) 的值(假设有 (m)(0)),根据上面的递推可以得出 (f_m=max {cnt_i+[pos_i\%2=1]+(m-i)})(因为根据 (f_{i-1}+1) 转移的一定是一段后缀,所以这个式子是对的)。需要注意的是,对于 (f_i=0)(i) 不能被算入其中。

    (x) 变为 (x+1),只会多出一个 (0),上述公式的三个部分都容易用线段树直接维护。但 (f_i=0)(i) 不能被算入,这个只需暴力删除即可,因为这样的 (i) 构成 ([1,n]) 的一段前缀,每次不断向后检查并在线段树上单点修改,每个数只会被处理 (1) 次。

    #include <bits/stdc++.h>
    using namespace std;
    void read (int &x) {
        char ch = getchar(); x = 0; while (!isdigit(ch)) ch = getchar();
        while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
    } const int N = 2e5 + 5, inf = 1e9;
    int n, a[N], p[N], k[N];
    struct tree {
        int c[N << 2], tag[N << 2];
        #define ls (p << 1)
        #define rs (p << 1 | 1)
        void build (int p, int l, int r) {
            c[p] = -inf, tag[p] = 0; if (l == r) return;
            int mid (l + r >> 1);
            build (ls, l, mid), build (rs, mid + 1, r);
        }
        void push_down (int p) {
            if (tag[p]) {
                tag[ls] += tag[p], tag[rs] += tag[p];
                c[ls] += tag[p], c[rs] += tag[p]; tag[p] = 0;
            }
        }
        void modify (int p, int l, int r, int ql, int qr, int v) {
            if (ql <= l && r <= qr) {
                c[p] += v, tag[p] += v; return;
            }
            int mid (l + r >> 1); push_down (p);
            if (ql <= mid) modify (ls, l, mid, ql, qr, v);
            if (qr > mid) modify (rs, mid + 1, r, ql, qr, v);
            c[p] = max (c[ls], c[rs]);
        }
        void update (int p, int l, int r, int x, int v) {
            if (l == r) { c[p] = v; return; }
            int mid (l + r >> 1); push_down (p);
            if (x <= mid) update (ls, l, mid, x, v);
            else update (rs, mid + 1, r, x, v);
            c[p] = max (c[ls], c[rs]);
        }
    } t;
    struct BIT {
        int c[N];
        void clear () {
            memset (c, 0, (n + 1) * sizeof (int));
        }
        int add (int x) {
            for (; x <= n; x += (x & -x)) ++c[x];
        }
        int ask (int x) {
            int s = 0; for (; x; x -= (x & -x)) s += c[x]; return s;
        }
    } cnt;
    void del (int &now) {
        while (now <= n && k[now]) t.update (1, 1, n, now, -inf), ++now;
    }
    signed main() {
        int T; read (T);
        while (T--) {
            read (n); cnt.clear (); t.build (1, 1, n);
            memset (k, 0, (n + 1) * sizeof (int));
            for (int i = 1; i <= n; ++i) read (a[i]), p[a[i]] = i;
            int res = 0, now = 1;
            // t.build (1, 1, n);
            for (int i = 1; i <= n; ++i) {
                int x = p[i]; k[x] = 1;
                t.modify (1, 1, n, x, n, -1);
                t.modify (1, 1, n, 1, x, 1);
                int tmp = cnt.ask (x);
                t.update (1, 1, n, x, (x & 1) + (x - 1 - tmp) + (i - 1 - tmp));
                cnt.add (x); del (now);
                res = max (res, t.c[1]);
            }
            printf ("%d
    ", res);
        }
        return 0;
    }
    
  • 相关阅读:
    Java 8 的内存结构
    数据库锁和隔离级别
    MySQL中的where和having
    单例对象线程安全问题
    计算机速成课 第6集:寄存器 & 内存
    多叉树的深度优先和广度优先遍历
    javascript中异步任务的执行顺序
    错误:C2062:意外的类型"unsigned int"问题的排查
    键值类型QMap、QHash等区别
    qt中文不相等问题
  • 原文地址:https://www.cnblogs.com/whx666/p/15239930.html
Copyright © 2020-2023  润新知