P3928 SAC E#1 - 一道简单题 Sequence2 线段树优化 dp

小强拿到一个3×n的数组,要在每一列选一个数(或者不选),满足以下条件:

1.如果在第一行选,那它必须大于等于上一个数

2.如果在第二行选,那么必须小于等于上一个数

3.如果在第三行选,对于连续的一段在第三行选的数,必须满足方向相同(都小于等于上一个数或者都大于等于上一个数)

扫描二维码关注公众号,回复: 7100886 查看本文章

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
/////////////////////////////////////
const int N=3e5+100;
int maxx[5][N<<2],nn,n,b[N<<2],dp[N][5],ans,a[N][4];
void upnode(int id,int x,int v,int l,int r,int pos)
{
    if(l==r){maxx[id][pos]=max(maxx[id][pos],v);return ;}
    int m=(l+r)>>1;
    if(x<=m)upnode(id,x,v,l,m,pos<<1);
    else upnode(id,x,v,m+1,r,pos<<1|1);
    maxx[id][pos]=max(maxx[id][pos<<1],maxx[id][pos<<1|1]);
}
int qmaxx(int id,int L,int R,int l,int r,int pos)
{
    if(L<=l&&r<=R)return maxx[id][pos];
    int m=(l+r)>>1;int ans=0;
    if(L<=m)ans=max(ans,qmaxx(id,L,R,l,m,pos<<1));
    if(R>m)ans=max(ans,qmaxx(id,L,R,m+1,r,pos<<1|1));
    return ans;
}
int main()
{
    scanf("%d",&n);
    rep(i,1,n)scanf("%d",&a[i][1]),b[++nn]=a[i][1];
    rep(i,1,n)scanf("%d",&a[i][2]),b[++nn]=a[i][2];
    rep(i,1,n)scanf("%d",&a[i][3]),b[++nn]=a[i][3];
    sort(b+1,b+1+nn);
    nn=unique(b+1,b+1+nn)-b-1;
    rep(i,1,n)a[i][1]=lower_bound(b+1,b+1+nn,a[i][1])-b,
    a[i][2]=lower_bound(b+1,b+1+nn,a[i][2])-b,
    a[i][3]=lower_bound(b+1,b+1+nn,a[i][3])-b;

    rep(i,1,n)
    {
        dp[i][1]=max(dp[i][1],qmaxx(1,1,a[i][1],1,nn,1));
        dp[i][1]=max(dp[i][1],qmaxx(2,1,a[i][1],1,nn,1));
        dp[i][1]=max(dp[i][1],qmaxx(3,1,a[i][1],1,nn,1));
        dp[i][1]=max(dp[i][1],qmaxx(4,1,a[i][1],1,nn,1));
        dp[i][1]++;

        dp[i][2]=max(dp[i][2],qmaxx(1,a[i][2],nn,1,nn,1));
        dp[i][2]=max(dp[i][2],qmaxx(2,a[i][2],nn,1,nn,1));
        dp[i][2]=max(dp[i][2],qmaxx(3,a[i][2],nn,1,nn,1));
        dp[i][2]=max(dp[i][2],qmaxx(4,a[i][2],nn,1,nn,1));
        dp[i][2]++;

        dp[i][3]=max(dp[i][3],qmaxx(1,1,a[i][3],1,nn,1));
        dp[i][3]=max(dp[i][3],qmaxx(2,1,a[i][3],1,nn,1));
        dp[i][3]=max(dp[i][3],qmaxx(3,1,a[i][3],1,nn,1));
        dp[i][3]++;

        dp[i][4]=max(dp[i][4],qmaxx(1,a[i][3],nn,1,nn,1));
        dp[i][4]=max(dp[i][4],qmaxx(2,a[i][3],nn,1,nn,1));
        dp[i][4]=max(dp[i][4],qmaxx(4,a[i][3],nn,1,nn,1));
        dp[i][4]++;

        upnode(1,a[i][1],dp[i][1],1,nn,1);
        upnode(2,a[i][2],dp[i][2],1,nn,1);
        upnode(3,a[i][3],dp[i][3],1,nn,1);
        upnode(4,a[i][3],dp[i][4],1,nn,1);
    }
    rep(i,1,n)
    rep(j,1,4)
    ans=max(ans,dp[i][j]);
    cout<<ans;

    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/bxd123/p/11412367.html
今日推荐