题解
- 首先,我们先求出两个东西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 }