所有数(in[1,1e5])
(n^2)枚举点,再枚举操作,判哪些点对不合法
看错题,变化不是累加的
思考:
(f_i,i)结束最大值
转移条件((j o i)):
- (max_jleq a_i)
- (a_jleq min_i)
没想到:
算上时间就是三维偏序,CDQ分治解决
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
const int N=1e5+4;
int n,m,ans,a[N],mx[N],mn[N],t[N],f[N],c[N];
inline bool comp_1(int x,int y){return mx[x]<mx[y];}
inline bool comp_2(int x,int y){return a[x]<a[y];}
inline void add(int x,int v){
for(;x<=n;x+=x&-x)t[x]=max(t[x],v);
}
inline void clear(int x){
for(;x<=n;x+=x&-x)t[x]=0;
}
inline int ask(int x){
int ret=0;
for(;x;x-=x&-x)ret=max(ret,t[x]);
return ret;
}
void cdqz(int ql,int qr){
if(ql==qr){if(!f[ql])f[ql]=1;return;}
int mid=ql+qr>>1;
cdqz(ql,mid);
for(int i=ql;i<=qr;i++)c[i]=i;
sort(c+ql,c+mid+1,comp_1);
sort(c+mid+1,c+qr+1,comp_2);
for(int i=mid+1,j=ql;i<=qr;i++){
while(j<=mid&&mx[c[j]]<=a[c[i]]){
add(a[c[j]],f[c[j]]);
j++;
}
f[c[i]]=max(f[c[i]],ask(mn[c[i]])+1);//c[i]
}
for(int i=ql;i<=mid;i++)clear(a[c[i]]);
cdqz(mid+1,qr);
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=mn[i]=mx[i]=read();
for(int i=1,x,v;i<=m;i++){
x=read();v=read();
mn[x]=min(mn[x],v);
mx[x]=max(mx[x],v);
}
cdqz(1,n);
for(int i=1;i<=n;i++)ans=max(ans,f[i]);
cout<<ans;
return (0-0);
}