有一个长度为n的序列和m个询问。
每个询问:将a[u]替换成v后,最长严格上升子序列的长度。
每个询问互相独立。
n,m<=5e5
分类讨论。
a[u]被修改为v时,严格上升子序列有两种,一种是不含位置u的,一种是含位置u的。
不含u的,需要预处理出每个询问的v顺着做的排名f1[i],倒着做的排名g1[i]。
设f[i],g[i]表示顺着/倒着做,i在lis中的排名。
如果删去a[u]后,仍然有元素j,满足f[i]=f[j],g[i]=g[j],且f[i]+g[i]-1=lis,那么lis不会减小。
如果含v,那么那么f1[i]+g1[i]-1则是这种情况的最佳答案。
#include
#include
#include
#include
#include
#define N 500010
#define Q 8388608
#define Inf 2147483647
#define P(a) putchar(a)
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct noq{
int u,v,id;
}qu[N];
int ti[N];
int a[N],b[N],c[N],f[N],g[N];
int f1[N],g1[N];
int L[N],R[N],tar[N],ans[N],ha[Q],Ha[Q];
int i,j,k,l1,r1,mid;
int n,m,x,wz,lis,cs,Lis,z[N];
int u,v,w,w1,Mx,Mn,W;
int opl,opr,opx,opz;
int read(){
int fh=0,rs=0;char ch=0;
while((ch<'0'||ch>'9')&&(ch^'-'))ch=getchar();
if(ch=='-')fh=1,ch=getchar();
while(ch>='0'&&ch<='9')rs=(rs<<3)+(rs<<1)+(ch^'0'),ch=getchar();
return fh?-rs:rs;
}
void write(int x){
if(x>9)write(x/10);
P(x%10+'0');
}
int hash(int x){
int y=x&(Q-1);
while(ha[y]&&ha[y]!=x)y=(y+1)&(Q-1);
ha[y]=x;
return y;
}
int ef(int L,int R,int num){
int x=R,Mid;
while(L<=R){
Mid=(L+R)>>1;
if(c[Mid]>num)x=Mid,R=Mid-1;else L=Mid+1;
}
return x;
}
int ef1(int L,int R,int num){
int x=R,Mid;
while(L<=R){
Mid=(L+R)>>1;
if(c[Mid]<num)x=Mid,R=Mid-1;else L=Mid+1;
}
return x;
}
int Max(int x,int y){return x>y?x:y;}
int Min(int x,int y){return x<y?x:y;}
bool cmp(noq a,noq b){return a.u<b.u||(a.u==b.u&&a.v<b.v);}
bool cmp1(noq a,noq b){return a.u>b.u||(a.u==b.u&&a.v>b.v);}
bool cmp2(noq a,noq b){return a.id<b.id;}
int main(){
n=read();m=read();
fo(i,1,n)a[i]=read();
fo(i,1,m)qu[i].u=read(),qu[i].v=read(),qu[i].id=i;
sort(qu+1,qu+m+1,cmp);
lis=0;W=1;
fo(i,1,n){
c[lis+1]=Inf;
while(W<=m&&qu[W].u==i){
wz=ef(1,lis+1,qu[W].v);
if(c[wz-1]==qu[W].v)wz--;
f1[qu[W].id]=wz;
W++;
}
wz=ef(1,lis+1,a[i]);
if(c[wz-1]<a[i]){
f[i]=f[b[wz-1]]+1;
c[wz]=a[i];
b[wz]=i;
if(wz==lis+1)lis++;
}else f[i]=f[b[wz-1]];
}
fo(i,1,n)b[i]=0;
Lis=lis;lis=0;
c[0]=Inf;
sort(qu+1,qu+m+1,cmp1);
W=1;
fd(i,n,1){
c[lis+1]=Inf;
while(W<=m&&qu[W].u==i){
wz=ef1(1,lis+1,qu[W].v);
if(c[wz-1]==qu[W].v)wz--;
g1[qu[W].id]=wz;
W++;
}
wz=ef1(1,lis+1,a[i]);
if(c[wz-1]>a[i]){
g[i]=g[b[wz-1]]+1;
c[wz]=a[i];
b[wz]=i;
if(wz==lis+1)lis++;
}else g[i]=g[b[wz-1]];
if(f[i]+g[i]-1==Lis){
z[i]=(1ll*123456789*f[i]+g[i])%1000000007;
w=hash(z[i]);
Ha[w]++;
}
}
sort(qu+1,qu+m+1,cmp2);
fo(i,1,m){
w=hash(z[qu[i].u]);
if(Ha[w]>1||w==0)ans[i]=Lis;else ans[i]=Lis-1;
ans[i]=Max(ans[i],f1[i]+g1[i]-1);
write(ans[i]);P('\n');
}
return 0;
}