! TJOI/HEOI2016序列

所有数\(\in[1,1e5]\)
\(n^2\)枚举点,再枚举操作,判哪些点对不合法
看错题,变化不是累加的
思考:
\(f_i,i\)结束最大值
转移条件\((j\to i)\):
- \(max_j\leq a_i\)
- \(a_j\leq 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);
}
作者:starusc
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号