• [dp][lis] Jzoj P5920 风筝


    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

    题解

    • 首先,我们先求出两个东西lis1和lis2,分别为以i结尾和以i为开始的lis
    • 然后再来考虑一下修改后的情况
    • ①a在lis中 ②a不在lis中
    • 如果a在lis中,如果当前修改的数的lis1+lis2-1大于lis那么直接输出
    • 还有一种情况也就是修改后lis就变短了,但是呢,lis可能会有多个,也就是说如果当前这个位修改后有没有其它lis来替换
    • 举个例子:1245,这个显然有两个lis,①124 ②125
    • 如果修改4为1后,第一个lis显然会变短,但是对第二个没有影响
    • 那么就可以这样做,将lis的每一个位置不同的数都++,也就是d[lis1[i]]++,因为lis1是以i结尾的lis的长度,那么其实就是在lis中的位置
    • 最后一种情况就是a不在lis中,那就简单了,直接输出lis的长度

    代码

     1 #include <cstdio> 
     2 #include <iostream>
     3 #include <cstring> 
     4 #include <algorithm>
     5 #define N 500010
     6 #define inf 0x3f3f3f3f
     7 using namespace std;
     8 struct edge{int x,d,v,a,b;}Q[N];
     9 int n,m,len,l,h[N],lis1[N],lis2[N],ans[N],k[N],f[N];
    10 bool cmp(edge a,edge b){ return a.x<b.x; } 
    11 int main()
    12 {
    13     freopen("kite.in","r",stdin),freopen("kite.out","w",stdout);
    14     scanf("%d%d",&n,&m);
    15     for (int i=1;i<=n;i++) scanf("%d",&h[i]);
    16     for (int i=1,x,y;i<=m;i++) scanf("%d%d",&Q[i].x,&Q[i].v),Q[i].d=i;
    17     sort(Q+1,Q+m+1,cmp);
    18     l=1;
    19     for (int i=1;i<=n;i++) f[i]=inf;
    20     for (int i=1;i<=n;i++) 
    21     {
    22         while (l<=m&&Q[l].x==i)
    23         {
    24             int p=lower_bound(f+1,f+n+1,Q[l].v)-f;
    25             Q[l].a=p,l++;
    26         }
    27         int p=lower_bound(f+1,f+n+1,h[i])-f;
    28         lis1[i]=p,f[p]=h[i],len=max(p,len);
    29     }
    30     l=m;
    31     for (int i=1;i<=n;i++) f[i]=inf;
    32     for (int i=n;i>=1;i--) 
    33     {
    34         while (l>0&&Q[l].x==i)
    35         {
    36             int p=lower_bound(f+1,f+n+1,-Q[l].v)-f;
    37             Q[l].b=p,l--;
    38         }
    39         int p=lower_bound(f+1,f+n+1,-h[i])-f;
    40         lis2[i]=p,f[p]=-h[i];
    41     }
    42     for (int i=1;i<=n;i++) if (lis1[i]+lis2[i]-1==len) k[lis1[i]]++;
    43     for (int i=1;i<=m;i++)
    44         if (Q[i].a+Q[i].b>len) ans[Q[i].d]=Q[i].a+Q[i].b-1;
    45         else if (lis1[Q[i].x]+lis2[Q[i].x]>len&&k[lis1[Q[i].x]]==1) ans[Q[i].d]=len-1;
    46         else ans[Q[i].d]=len;
    47     for (int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    48 }
  • 相关阅读:
    LOGO生成器
    【转】 iOS开发:Debug与Release版本NSLog屏蔽方法
    【转】IOS调试技巧:当程序崩溃的时候怎么办 iphone IOS
    【转】 Objective C实现多继承
    NSArray
    记一次 ios程序 内存优化记录LOG日志
    【转】[iOS] 关于 self = [super init];
    NSMutableArray
    Xcode调试利器 Instruments用户指南
    一段代码展现一个流程,流程在代码中内聚
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9833378.html
Copyright © 2020-2023  润新知