[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\n",ans[i]);
48 }

 

posted @ 2018-10-22 21:56  BEYang_Z  阅读(215)  评论(0编辑  收藏  举报