! TJOI/HEOI2016序列

所有数(in[1,1e5])

(n^2)枚举点,再枚举操作,判哪些点对不合法

看错题,变化不是累加的

思考:

(f_i,i)结束最大值

转移条件((j o i))

  1. (max_jleq a_i)
  2. (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);
}
原文地址:https://www.cnblogs.com/aurora2004/p/12738060.html