zoukankan      html  css  js  c++  java
  • [二分][LIS]JZOJ 5920 风筝

    Description

               当一阵风吹来,风筝飞上天空,为了你,而祈祷,而祝福,而感动……
    Description
             oyiya 在 AK 了 IOI 之后来到了乡下,在田野中玩耍,放松身心。
             他发现前面有一排小朋友在放风筝,每一个风筝有一个高度 hi,风筝的高度可能会随着小朋友的心情而改变。这时,毒瘤的 oyiya 有了一个毒瘤的 idea,他想知道改变高度之后风筝的最长严格上升子序列。oyiya 太强了表示并不想做这种水题,你能解决这个问题吗?
     

    Input

            第一行为两个整数 n, m,表示小朋友的个数和询问数。
            第二行有 n 个整数,表示 hi。
            接下来 m 行,每行两个整数 ai, bi,表示询问将第 ai 只风筝的高度变成 bi 后的 LIS。注意询问之间是独立的,后面的询问不受前面询问的影响.

    Output

    m 行,每行一个整数表示询问的答案。
     

    Sample Input

    3 3
    2 2 3
    1 3
    1 1
    3 2

    Sample Output

    2
    3
    1
     

    Data Constraint

    分析

    这个其实挺简单的,我们先看一下有哪些情况,显然只有两种:

    1、更改的数不在原最长不下降子序列中,直接输出原LIS(或通过该数产生的新LIS)

    2、更改的数在原最长不下降子序列中,这时候要分类讨论:如果有替代的数(即在原LIS中排名相同)则是原序列长,否则原长-1

    关于排名大佬们可以采用主席树

    像我们这种菜鸡只能离线,排序询问以后求出包括询问及询问之前的LIS和包括询问及询问以后的LIS(正反做一遍nlogn求即可)

    然后判断两LIS长之和-1是否为原LIS长,是则在LIS中,顺便用这个维护同排名出现次数

    最后要吐槽出题人的是实际数据范围5e5

    #include <iostream> 
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N=5e5+10;
    struct Task {
        int x,y,id,rnkpre,rnknex;
    }q[N];
    int lispre[N],lisnex[N];
    int d[N],h[N],belis[N],ans[N];
    int n,m,len;
    
    bool Cmp(Task a,Task b) {
        return a.x<b.x;
    }
    
    int main() {
        freopen("kite.in","r",stdin);
        freopen("kite.out","w",stdout);
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%d",&h[i]);
        for (int i=1;i<=m;i++) scanf("%d%d",&q[i].x,&q[i].y),q[i].id=i;
        sort(q+1,q+m+1,Cmp);
        for (int i=1;i<=n;i++) d[i]=2147483647;
        int st=1;
        for (int i=1;i<=n;i++) {
            for (;st<=m&&q[st].x==i;st++) {
                int justanumber=lower_bound(d+1,d+n+1,q[st].y)-d;
                q[st].rnkpre=justanumber;
            }
            int justanumber=lower_bound(d+1,d+n+1,h[i])-d;
            lispre[i]=justanumber;d[justanumber]=h[i];
            len=max(len,justanumber);
        }
        st=m;
        for (int i=1;i<=n;i++) d[i]=2147483647;
        for (int i=n;i;i--) {        
            for (;st&&q[st].x==i;st--) {
                int justanumber=lower_bound(d+1,d+n+1,-q[st].y)-d;
                q[st].rnknex=justanumber;
            }
            int justanumber=lower_bound(d+1,d+n+1,-h[i])-d;
            lisnex[i]=justanumber;d[justanumber]=-h[i];
        }
        for (int i=1;i<=n;i++)
            if (lispre[i]+lisnex[i]-1==len) belis[lispre[i]]++;
        for (int i=1;i<=m;i++) {
            if (q[i].rnkpre+q[i].rnknex>len) ans[q[i].id]=q[i].rnkpre+q[i].rnknex-1;
            else if (lispre[q[i].x]+lisnex[q[i].x]-1==len&&belis[lispre[q[i].x]]==1) ans[q[i].id]=len-1;
            else ans[q[i].id]=len;
        }
        for (int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    N-Queens
    Pow(x, n)
    Maximum Subarray
    Spiral Matrix
    Jump Game
    Merge Intervals
    Insert Interval
    Length of Last Word
    Spiral Matrix II
    Amazon 面经
  • 原文地址:https://www.cnblogs.com/mastervan/p/9833358.html
Copyright © 2011-2022 走看看