码迷,mamicode.com
首页 > 其他好文 > 详细

「luogu4093」[HEOI2016/TJOI2016]序列

时间:2018-03-12 01:04:29      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:min   print   names   clu   处理   pid   lin   amp   cdq分治   

写出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 }

 

树套树:

「luogu4093」[HEOI2016/TJOI2016]序列

标签:min   print   names   clu   处理   pid   lin   amp   cdq分治   

原文地址:https://www.cnblogs.com/mycups/p/8546976.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!