题解:P11187 配对序列

大家好,我非常喜欢线段树优化 dp,于是我使用线段树优化 dp 通过了这道题目。

前排提醒:本题解做法时间复杂度带一只 log\log,如果想要学习 O(n)\operatorname{O}(n) 做法请自行略过。

Solution P11187

Idea

不难发现配对序列就是形如 {a,a,b,b,c,c,d,d,}\{a,a,b,b,c,c,d,d,\cdots\} 的序列。

我们设 dpi,0/1dp_{i,0/1} 为当前最后一个数为 ii,这个数出现在第奇数个位置(表示为 00)还是在第偶数个位置(表示为 11)的最长配对序列的长度。

显然有:dpi,1=dpi,0+1dp_{i,1}=dp_{i,0}+1dpi,0=max{dp1,1,dp2,1,,dpai1,1,dpai+1,1,dpai+2,1,,dp500000,1}+1dp_{i,0}=\max\{dp_{1,1},dp_{2,1},\cdots,dp_{a_i-1,1},dp_{a_i+1,1},dp_{a_i+2,1},\cdots,dp_{500000,1}\}+1

解释一下:如果这个数是第偶数个位置,它前面一个必须是它自己。如果是第奇数个位置,只要前一个位置不是它自己都可以转移。另外,500000500000 是题目中给定的 aia_i 的最大值。

这样的复杂度是 O(n2)\operatorname{O}(n^2) 的,瓶颈在于 dpi,0dp_{i,0} 的转移。

考虑优化。

我们发现后面转移 dpi,0dp_{i,0} 的式子实际上就是 [1,a[i]1][1,a[i]-1][a[i]+1,500000][a[i]+1,500000] 两个区间最大值的最大值。

求区间最大值,不难联想到线段树。

这样我们把 dpi,1dp_{i,1} 的信息维护到线段树里,开一个数组记录 dpi,0dp_{i,0},然后就可以转移了。

最后答案显然是 max{dpi,1}\max\{dp_{i,1}\}i[1,500000]i\in[1,500000]),线段树上其实就是 11 号区间,所以输出 tr1tr_1 即可(trtr 为维护线段树的数组)。

这样复杂度就是只带一只 log\log 的了。

Code

代码中的 dpdp 数组相当于记录上文中 dpi,0dp_{i,0} 的数组。

#include<bits/stdc++.h>
#define ls now<<1
#define rs (now<<1)|1
using namespace std;
const int N=500005;
int dp[N],tr[N<<2],n,a[N];
void add(int l,int r,int p,int now,int x){
    if(l==r&&l==p){
        tr[now]=max(tr[now],x);
        return;
    }
    int mid=(l+r)>>1;
    if(p<=mid)add(l,mid,p,ls,x);
    else add(mid+1,r,p,rs,x);
    tr[now]=max(tr[ls],tr[rs]);
}
int query(int l,int r,int al,int ar,int now){
    if(al>ar)return 0;
    if(al<=l&&r<=ar)return tr[now];
    int mid=(l+r)>>1,res=0;
    if(al<=mid)res=max(res,query(l,mid,al,ar,ls));
    if(ar>mid)res=max(res,query(mid+1,r,al,ar,rs));
    return res;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;i++){
        if(dp[a[i]]!=0)add(1,500000,a[i],1,dp[a[i]]+1);
        int res=max(query(1,500000,1,a[i]-1,1),query(1,500000,a[i]+1,500000,1));
        dp[a[i]]=res+1;
    }
    printf("%d",tr[1]);
}
posted @   Weslie_qwq  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示