zoukankan      html  css  js  c++  java
  • 「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 }
  • 相关阅读:
    nginx申请并配置免费https
    linux安装git
    linux安装openssl
    nginx配置支持http2
    linux服务器升级nginx
    linux 增加虚拟内存swap(使用文件)
    使用shell安装lnmp
    mysql 数据库主从同步
    Android四大组件之Service
    Android四大组件之Activity
  • 原文地址:https://www.cnblogs.com/mycups/p/8546976.html
Copyright © 2011-2022 走看看