1. 程式人生 > 其它 >CF1575L Longest Array Deconstruction 題解

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 或 樹狀陣列來解決它啦。

注意:上面的兩個條件中一個是小於號,另一個是小於等於號(其實這樣反而更簡單了)。

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\_ \]

本文來自部落格園,作者:xixike,轉載請註明原文連結:https://www.cnblogs.com/xixike/p/15721272.html