「luogu4093」[HEOI2016/TJOI2016]序列

写出dp方程,可以发现转移要满足一个三维偏序,那么可以处理三维偏序的方法优化。

CDQ分治:

  cdq分治和树状数组是好伙伴~

  注意分治的顺序,要保证先求解出所有前驱状态。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100010;
 4 int n,m,dp[N],maxn;
 5 struct Node{
 6     int a,maxv,minv,id;
 7 }node[N];
 8 int cmpa(const Node& x,const Node& y){return x.a<y.a;}
 9 int cmpv(const Node& x,const Node& y){return x.maxv<y.maxv;}
10 int cmpid(const Node& x,const Node& y){return x.id<y.id;}
11 int bit[N];
12 inline int lowbit(int k){return k&(-k);}
13 inline void change(int k,int x){while(k<=maxn) bit[k]=max(bit[k],x),k+=lowbit(k);return;}
14 inline int que(int k){
15     int ans=0;
16     while(k) ans=max(bit[k],ans),k-=lowbit(k);
17     return ans;
18 }
19 inline void reset(int k){
20     while(k<=maxn){
21         if(!bit[k]) return;
22         bit[k]=0,k+=lowbit(k);
23     }
24     return;
25 }
26 void cdq(int l,int r){
27     if(l>=r) return;
28     int mid=(l+r)>>1;
29     cdq(l,mid);
30     sort(node+l,node+mid+1,cmpv);sort(node+mid+1,node+r+1,cmpa);
31     int pl=l,pr=mid+1;
32     while(pl<=mid&&pr<=r){
33         if(node[pl].maxv<=node[pr].a){
34             change(node[pl].a,dp[node[pl].id]);
35             pl++;
36         }else{
37             dp[node[pr].id]=max(dp[node[pr].id],que(node[pr].minv)+1);
38             pr++;
39         }
40     }
41     while(pr<=r){
42         dp[node[pr].id]=max(dp[node[pr].id],que(node[pr].minv)+1);
43         pr++;
44     }
45     for(int i=l;i<=mid;i++) reset(node[i].a);
46     sort(node+l,node+r+1,cmpid);
47     cdq(mid+1,r);
48     return;
49 }
50 int main(){
51     int t1,t2;
52     scanf("%d%d",&n,&m);
53     for(int i=1;i<=n;i++) scanf("%d",&node[i].a),node[i].maxv=node[i].minv=node[i].a,node[i].id=i,dp[i]=1,maxn=max(maxn,node[i].a);
54     while(m--){
55         scanf("%d%d",&t1,&t2);
56         maxn=max(maxn,t2);
57         node[t1].maxv=max(node[t1].maxv,t2);
58         node[t1].minv=min(node[t1].minv,t2);
59     }
60     cdq(1,n);
61     int ans=0;
62     for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
63     printf("%d",ans);
64     return 0;
65 }

 

树套树:

  树状数组套线段树:

    注意线段树数组开足够大。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100010;
 4 int n,m,a[N],maxv[N],minv[N],maxn;
 5 int root[N];
 6 inline int read(){
 7     int x=0,w=1;char c=0;
 8     while(c<'0'||c>'9'){if(c=='-') w=-1;c=getchar();}
 9     while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
10     return x*w;
11 }
12 struct Segtree{
13     int ls[N<<6],rs[N<<6],v[N<<6],tot;
14     inline void pushup(int k){
15         v[k]=max(v[ls[k]],v[rs[k]]);
16         return;
17     }
18     int que(int k,int l,int r,int pos){
19         if(!k) return 0;
20         if(l==r) return v[k];
21         int mid=(l+r)>>1;
22         if(pos<=mid) return que(ls[k],l,mid,pos);
23         else return max(v[ls[k]],que(rs[k],mid+1,r,pos));
24     }
25     void modify(int& k,int l,int r,int pos,int x){
26         if(!k) k=++tot;
27         if(l==r){v[k]=max(v[k],x);return;}
28         int mid=(l+r)>>1;
29         if(pos<=mid) modify(ls[k],l,mid,pos,x);
30         else modify(rs[k],mid+1,r,pos,x);
31         pushup(k);
32         return;
33     }
34 }segtree;
35 struct Bit{
36     inline int lowbit(int k){return k&(-k);}
37     int que(int bitpos,int segpos){
38         int ans=0;
39         while(bitpos){
40             ans=max(ans,segtree.que(root[bitpos],1,maxn,segpos));
41             bitpos-=lowbit(bitpos);
42         }
43         return ans;
44     }
45     void modify(int bitpos,int segpos,int x){
46         while(bitpos<=maxn){
47             segtree.modify(root[bitpos],1,maxn,segpos,x); 
48             bitpos+=lowbit(bitpos);
49         }
50         return;
51     }
52 }bit;
53 int main(){
54     int t1,t2;
55     n=read(),m=read();
56     for(int i=1;i<=n;i++) a[i]=minv[i]=maxv[i]=read(),maxn=max(maxn,a[i]);
57     while(m--){
58         t1=read(),t2=read();
59         maxn=max(maxn,t2);
60         minv[t1]=min(minv[t1],t2),maxv[t1]=max(maxv[t1],t2);
61     }
62     int d,ans;
63     for(int i=1;i<=n;i++){
64         d=bit.que(a[i],minv[i])+1;
65         bit.modify(maxv[i],a[i],d); 
66         ans=max(ans,d);
67     }
68     printf("%d",ans);
69     return 0;
70 }

 

posted @ 2018-03-11 23:24  Cupcake  阅读(140)  评论(0编辑  收藏  举报