Codeforces Round #345 (Div. 1) D - Zip-line 带单点修改的LIS 主席树 | 离线树状数组

原文链接: http://www.cnblogs.com/CJLHY/p/9699650.html

D - Zip-line

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>

using namespace std;

const int N = 4e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;

int n, m, tot, h[N], hs[N], dp[2][N], stk[N], cnt[N], LIS;
bool is[N];

struct ChairmanTree {
    struct node {
        int mx, l, r;
    } a[N * 20];
    int tot, root[N];
    void update(int p, int val, int l, int r, int &x, int y) {
        x = ++tot; a[x] = a[y];
        a[x].mx = max(a[x].mx, val);
        if(l == r) return ;
        int mid = l + r >> 1;
        if(p <= mid) update(p, val, l, mid, a[x].l, a[y].l);
        else update(p, val, mid + 1, r, a[x].r, a[y].r);
    }
    int query(int L, int R, int l, int r, int x) {
        if(hs[r] < L || hs[l] > R) return 0;
        if(hs[l] >= L && hs[r] <= R) return a[x].mx;
        int ans = 0, mid = l + r >> 1;
        if(L <= hs[mid]) ans = query(L, R, l, mid, a[x].l);
        if(R > hs[mid]) ans = max(ans, query(L, R, mid + 1, r, a[x].r));
        return ans;
    }
}ct[2];

void getLIS() {
    memset(stk, inf, sizeof(stk));
    for(int i = 1; i <= n; i++) {
        dp[0][i] = lower_bound(stk, stk + N, h[i]) - stk + 1;
        stk[dp[0][i] - 1] = h[i];
        LIS = max(LIS, dp[0][i]);
    }
    memset(stk, inf, sizeof(stk));
    for(int i = n; i >= 1; i--) {
        dp[1][i] = lower_bound(stk, stk + N, -h[i]) - stk + 1;
        stk[dp[1][i] - 1] = -h[i];
    }
    for(int i = 1; i <= n; i++) {
        if(dp[0][i] + dp[1][i] == LIS + 1) {
            is[i] = true;
            cnt[dp[0][i]]++;
        }
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &h[i]);
        hs[++tot] = h[i];
    }
    sort(hs + 1, hs + 1 + tot);
    tot = unique(hs + 1, hs + 1 + tot) - hs - 1;

    for(int i = 1; i <= n; i++)
        h[i] = lower_bound(hs + 1, hs + 1 + tot, h[i]) - hs;
    getLIS();

    for(int i = 1; i <= n; i++)
        ct[0].update(h[i], dp[0][i], 1, tot, ct[0].root[i], ct[0].root[i-1]);
    for(int i = n; i >= 1; i--)
        ct[1].update(h[i], dp[1][i], 1, tot, ct[1].root[i], ct[1].root[i+1]);

    while(m--) {
        int a, b;
        scanf("%d%d", &a, &b);
        int ans = is[a] ? LIS - 1 : LIS;
        ans = max(ans, ct[0].query(1, b - 1, 1, tot, ct[0].root[a-1])
                  + ct[1].query(b + 1, inf, 1, tot, ct[1].root[a+1]) + 1);
        if(is[a] && cnt[dp[0][a]] > 1) {
            ans = max(ans, LIS);
        }
        printf("%d\n", ans);
    }
    return 0;
}

/*
*/

转载于:https://www.cnblogs.com/CJLHY/p/9699650.html

猜你喜欢

转载自blog.csdn.net/weixin_30929295/article/details/94874777