bzoj 4553 && HEOI2016 day1t3 seq
一个序列在所有变换中都单调不降的条件是i<j,a[i]<=min[j],mx[i]<=a[j],所以套CDQ就行了。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #define N 100005 6 #define inf 0x3f3f3f3f 7 using namespace std; 8 int n,m; 9 int a[N]; 10 int f[N]; 11 int mx[N],mn[N]; 12 int tmp[N]; 13 int v[N]; 14 int res; 15 bool cmp(int x,int y) 16 { 17 if(x<=res&&y<=res)return mx[x]<mx[y]; 18 if(x<=res)return mx[x]<=a[y]; 19 if(y<=res)return a[x]<mx[y]; 20 return a[x]<a[y]; 21 } 22 int dp[N]; 23 struct node 24 { 25 int lazy,zhi; 26 }aa[N*8]; 27 void push_down(int x) 28 { 29 if(aa[x].lazy!=0) 30 { 31 aa[x*2].zhi=aa[x*2+1].zhi=-inf; 32 aa[x*2].lazy=aa[x*2+1].lazy=1; 33 aa[x].lazy=0; 34 } 35 return ; 36 } 37 int qur(int x,int l,int r,int ll,int rr) 38 { 39 if(l>=ll&&r<=rr) 40 { 41 return aa[x].zhi; 42 } 43 push_down(x); 44 int mid=(l+r)>>1; 45 if(rr<=mid)return qur(x*2,l,mid,ll,rr); 46 if(ll>mid)return qur(x*2+1,mid+1,r,ll,rr); 47 return max(qur(x*2,l,mid,ll,rr),qur(x*2+1,mid+1,r,ll,rr)); 48 } 49 void gai(int x,int l,int r,int pos,int z) 50 { 51 if(l==r) 52 { 53 aa[x].zhi=max(aa[x].zhi,z);return ; 54 } 55 push_down(x); 56 int mid=(l+r)>>1; 57 if(pos<=mid)gai(x*2,l,mid,pos,z); 58 else gai(x*2+1,mid+1,r,pos,z); 59 aa[x].zhi=max(aa[x*2].zhi,aa[x*2+1].zhi); 60 } 61 void solve(int l,int r) 62 { 63 if (l==r) 64 { 65 f[l]=max(f[l],1); 66 return ; 67 } 68 int mid=(l+r)>>1; 69 solve(l,mid);res=mid; 70 int cnt=0; 71 for(int i=l;i<=r;i++)tmp[++cnt]=i; 72 sort(tmp+1,tmp+cnt+1,cmp); 73 aa[1].lazy=1;aa[1].zhi=-inf; 74 for(int i=1;i<=cnt;i++) 75 { 76 if(tmp[i]<=mid)gai(1,1,100000,a[tmp[i]],f[tmp[i]]); 77 else f[tmp[i]]=max(f[tmp[i]],qur(1,1,100000,1,mn[tmp[i]])+1); 78 } 79 solve(mid+1,r); 80 } 81 int main() 82 { 83 scanf("%d%d",&n,&m); 84 memset(mx,0xcf,sizeof(mx)); 85 memset(mn,0x3f,sizeof(mn)); 86 for(int i=1;i<=n;i++) 87 { 88 scanf("%d",&a[i]); 89 mx[i]=mn[i]=a[i]; 90 } 91 for(int i=1;i<=m;i++) 92 { 93 int t1,t2; 94 scanf("%d%d",&t1,&t2); 95 mx[t1]=max(mx[t1],t2); 96 mn[t1]=min(mn[t1],t2); 97 } 98 solve(1,n); 99 int ans=1; 100 for(int i=1;i<=n;i++)ans=max(ans,f[i]); 101 printf("%d\n",ans); 102 return 0; 103 }