zoukankan      html  css  js  c++  java
  • CF1575L Longest Array Deconstruction 题解

    Description

    Luogu传送门

    Solution

    并不需要复杂的 DS(

    考虑对于两个点 \(x,y\ (x < y)\),什么情况下才能使它们都有贡献。

    第一个条件:

    \[a_x < a_y \]

    这个比较显然吧,就不多说了。

    第二个条件:

    \[x - a_x \leq y - a_y \]

    解释一下,\(x - a_x\) 表示在坐标 \(x\) 之前要删掉多少个数才能使 \(x = a_x\),显然对于 \(x,y\ (x < y)\)\(x\) 前删掉的数的个数必须小于等于 \(y\) 之前删掉的数的个数。

    同时,我们稍微推一下这个不等式,发现它也满足:

    \[x < y \]

    所以 \(x < y\) 这个条件我们就不需要处理了。

    推出上面这两个条件之后怎么做呢?

    然后……等等!这不就是一个二维偏序问题吗!

    于是我们就可以愉快的用 lower_bound 或 树状数组来解决它啦。

    注意:

    • 上面的两个条件中一个是小于号,另一个是小于等于号(其实这样反而更简单了),而我们计算出来的序列中可能会有大量相等的数,具体怎么写见代码吧。
    • 我们计算出的数列中会有许多 0,所以在树状数组的实现过程中要特判。

    Code

    (这里使用的树状数组)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace IO{
        inline int read(){
            int x = 0;
            char ch = getchar();
            while(!isdigit(ch)) ch = getchar();
            while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
            return x;
        }
    
        template <typename T> inline void write(T x){
            if(x > 9) write(x / 10);
            putchar(x % 10 + '0');
        }
    }
    using namespace IO;
    
    const int N = 2e5 + 10;
    struct node{
        int x, y;
        bool operator < (const node &b) const{
            return x != b.x ? x < b.x : y < b.y;
        }
    }a[N];
    int n, cnt, ans;
    
    struct BIT{
        int c[N];
    
        inline void add(int x, int y){
            if(x < 0) return;
            for(; x <= n; x += x & (-x)) c[x] = max(c[x], y);
        }
    
        inline int query(int x){
            if(x <= 0) return 0;
            int res = 0;
            for(; x; x -= x & (-x)) res = max(res, c[x]);
            return res;
        }
    }c;
    
    int main(){
        n = read();
        for(int i = 1; i <= n; ++i){
            int t = read();
            if(i - t >= 0) a[++cnt] = (node){i - t, t};
        }
        sort(a + 1, a + 1 + cnt);
        for(int i = 1; i <= cnt; ++i){
            int len = c.query(a[i].y - 1);
            c.add(a[i].y, len + 1);
            ans = max(ans, len + 1);
        }
        write(ans), puts("");
        return 0;
    }
    

    \[\_EOF\_ \]

  • 相关阅读:
    《编程人生》的书评
    目前流行的源程序版本管理软件和项目管理软件都有哪些, 各有什么优缺点?
    知识思考
    自我介绍
    使用my exclipse对数据库进行操作(3)
    猜数字简洁版
    SQL语句
    使用my exclipse对数据库进行操作(1)
    使用my exclipse对数据库进行操作(2)
    建筑平面图, 建筑设计图, 家具摆放图, 制作, 开发, 软件, VC++, 源代码组件库
  • 原文地址:https://www.cnblogs.com/xixike/p/15721272.html
Copyright © 2011-2022 走看看