题解:P15070 [UOI 2024 II Stage] Sequence
___AaAa_bBcCd___ · · 题解
题目链接:P15070 [UOI 2024 II Stage] Sequence
Part 1 动态规划设计
定义
若没有符合条件的
Part 2 线段树优化
当遍历到
也就是说,我们要支持单点修改和查询区间最大值。自然而然想到线段树。
Part 3 算法实现
由于末元素只可能是序列里出现过的元素,因此线段树也不需要开
然后我们二分出可以给
Part 4 参考代码
#include<bits/stdc++.h>
using namespace std;
const int N=500001;
int n,b[N],tot;
int s[N<<2],L[N<<2],R[N<<2];
long long l,r,a[N],c[N];
void build(int u,int l,int r){
L[u]=l,R[u]=r;
if(l<r){
int mid=(l+r)/2;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
}
}
int update(int u,int x,int k){
if(L[u]<=x&&x<=R[u]){
if(L[u]==R[u])return s[u]=max(s[u],k);
return s[u]=max(update(u*2,x,k),update(u*2+1,x,k));
}
return s[u];
}
int query(int u,int l,int r){
if(l>r||l>R[u]||L[u]>r)return 0;
if(l<=L[u]&&R[u]<=r)return s[u];
return max(query(u*2,l,r),query(u*2+1,l,r));
}
int find(long long x){
int l=1,r=tot,mid,ans=0;
while(l<=r){
mid=(l+r)/2;
if(c[mid]<=x)ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
int main(){
cin>>n>>l>>r;
for(int i=1;i<=n;i++)cin>>a[i],c[i]=a[i];
sort(c+1,c+1+n);
tot=unique(c+1,c+1+n)-(c+1);
build(1,1,tot);
for(int i=1;i<=n;i++)update(1,lower_bound(c+1,c+1+tot,a[i])-c,query(1,lower_bound(c+1,c+1+tot,l-a[i])-c,find(r-a[i]))+1);
cout<<s[1];
return 0;
}