• Educational Codeforces Round 97 (Rated for Div. 2)


    E. Make It Increasing Educational Codeforces Round 97 (Rated for Div. 2)

    题目连接

    题解:

    因为b[i]的值是确定,所以知道操作 b[i] 到b[i - 1]的区间, 当 (a[i] - a[j] < i - j (i > j)) 那么可以证明一定无法构成, 所以先判断是否可以构造,如果都满足, 那么对与每段 (b[i - 1])(b[i]) 可以先将(a[i] = a[i] - i)

    这样做的目的是保证存在 (a[i] > a[j] ,且 i > j) 那么就是且以 (b[i - 1])开始 (b[i]) 结束的最长上升子序列, 可以用二分优化到 n * log(n)也可以用线段树优化。

    代码:

        #include<bits/stdc++.h>
        using namespace std;
         
        const int N = 5e5 + 7;
        typedef long long ll;
         
        ll a[N], n, k, b[N];
        int rt;
         
        int tree[40 * N], ls[40 * N], rs[40 * N], dp[N];
        int top = 1;
        #define m (l + r) / 2
        void update(int v, int pos, int l, int r, int &node) {
            if (node == 0) node = top++;
            if (l == r) {
                tree[node] = v;
                return;
            }
            if (pos <= m) update(v, pos, l, m, ls[node]);
            else update(v, pos, m + 1, r, rs[node]);
            tree[node] = max(tree[ls[node]], tree[rs[node]]);
        }
         
        int query(int ql, int qr, int l, int r, int node) {
            if (ql <= l && qr >= r) {
                return tree[node];
            }
            int ans = 0;
            if (ql <= m) ans = max(ans, query(ql, qr, l, m, ls[node]));
            if (qr > m) ans = max(ans, query(ql, qr, m + 1, r, rs[node]));
            return ans;
        }
         
        int work(int l, int r) {
            int maxn = n + 2;
            for (int i = l; i <= r; i++) {
                dp[i] = 0;
            }
            for (int i = l + 1; i <= r; i++) {
                if (a[i] >= a[l]) {
                    dp[i] = 2;
                } else {
                    dp[i] = -1e8;
                }
            }
         
            for (int i = l + 1; i <= r; i++) {
                dp[i] = max(dp[i], query(1, a[i], 1, maxn, rt) + 1);
                if (dp[i] > 1)
                update(dp[i], a[i], 1, maxn, rt);
            }
         
            for (int i = l; i <= r; i++) {
                update(0, a[i], 1, maxn, rt);
            }
            
            if (dp[r] < 2) {
                return -1;
            }
            return (r - l + 1) - dp[r];
            
        }
         
        vector<int> g;
         
        int get_id(int x) {
            return lower_bound(g.begin(), g.end(), x) - g.begin() + 1;
        }
         
        int main() {
            ios::sync_with_stdio(0);
            cin >> n >> k;
            for (int i = 1; i <= n; i++) {
                cin >> a[i];
                a[i] = a[i] - i;
                g.push_back(a[i]);
            }
            sort(g.begin(), g.end());
            g.erase(unique(g.begin(), g.end()), g.end());
            for (int i = 1; i <= k; i++) {
                cin >> b[i];
            }
         
            for (int i = 1; i <= n; i++) {
                a[i] = get_id(a[i]);
            }
            b[0] = 0;
            b[k + 1] = n + 1;
            a[0] = 0;
            a[n + 1] = n + 2;
         
            int ans = 0;
         
            for (int i = 1; i <= k + 1; i++) {
                int cnt = work(b[i - 1], b[i]);
                if (cnt < 0) {
                    cout << -1 << endl;
                    return 0;
                }
                ans += cnt;
            }
            cout << ans << endl;
         
         
        }
    
  • 相关阅读:
    省选知识点
    寒假练习
    水题欢乐赛-套路
    2019年12月(2)
    洛谷P1347 排序
    Aizu
    2019年12月(1)
    【CSP2019】
    联系博主
    UVA1420 Priest John's Busiest Day【贪心】
  • 原文地址:https://www.cnblogs.com/BOZHAO/p/13894442.html
Copyright © 2020-2023  润新知