I . K-gap Subsequence
题目大意
A subsequence of a given sequence of integers is a subset of the values in the sequence in the same order. A kk-gap subsequence of a sequence of integers is a subsequence such that consecutive elements in the subsequence differ by at least kk. For example, the sequence
3, 12, 8, 4, 2, 5, 1, 9, 8, 6, 5, 1, 7
has a 4-gap subsequence of 3, 12, 8, 4, 9, 5, 1 and 7 (highlighted in bold above) since |3 - 12|, |12 - 8|, |8 - 4|, |4 - 9|, |9 - 5|, |5 - 1| and |1 - 7| are all 4 or greater.
Given a sequence and a value of kk, determine the length of the longest kk-gap subsequence.
Input
The first input line contains two space separated integers: nn (1≤n≤300,0001≤n≤300,000), indicating the length of the sequence, and kk (1≤k≤1091≤k≤109), indicating the value of kk for the input case.
The following input line contains nn space separated integers. The iith of these integers is aiai (1≤ai≤1091≤ai≤109 ), the ith value of the input sequence.
Output
Print the length of the longest kk-gap subsequence of the input sequence.
Samples
13 4 3 12 8 4 2 5 1 9 8 6 5 1 7
题解
这个题意就是给你n个数,然后让你从中选出一些子序列,使得相邻的两个数的绝对值小于k,这个题是一个线段树+dp,首先我们把这些数给他排序+离散化一下,然后我们操作了一个数,那么下一个数就是
从这些符合条件的已经操作晚的数中选一个
Code
#include<iostream> #include<algorithm> using namespace std; const int maxn=5e6+100; struct node{ int l,r; int ma; }t[maxn]; int a[maxn],b[maxn]; void push(int p){ t[p].ma=max(t[2*p].ma,t[2*p+1].ma); } void build(int p,int l,int r){ t[p].l=l; t[p].r=r; t[p].ma=0; if(l==r){ return ; } int mid=(l+r)/2; build(2*p,l,mid); build(2*p+1,mid+1,r); push(p); } void update(int p,int l,int x){ if(t[p].l==t[p].r){ t[p].ma=x; return ; } int mid=(t[p].l+t[p].r)/2; if(l<=mid){ update(2*p,l,x); } else{ update(2*p+1,l,x); } push(p); } int query(int p,int l,int r){ if(t[p].l>=l&&t[p].r<=r){ return t[p].ma; } int mid=(t[p].l+t[p].r)/2; int ans=0; if(l<=mid){ ans=max(ans,query(2*p,l,r)); } if(r>mid){ ans=max(ans,query(2*p+1,l,r)); } return ans; } int main(){ int n,k; cin>>n>>k; for(int i=1;i<=n;i++){ cin>>a[i]; b[i]=a[i]; } sort(b+1,b+n+1); int nn=unique(b+1,b+n+1)-(b+1); build(1,1,nn); int ans=0; for(int i=1;i<=n;i++){ int l=upper_bound(b+1,b+nn+1,a[i]-k)-b-1; int r=lower_bound(b+1,b+nn+1,a[i]+k)-b; int cnt=0; if(l>=1){ cnt=max(cnt,query(1,1,l)); } if(nn>=r){ cnt=max(cnt,query(1,r,nn)); } ans=max(ans,++cnt); //cout<<ans<<" cnt="<<cnt<<" "<<l<<" "<<r<<endl; int t=lower_bound(b+1,b+nn+1,a[i])-b; update(1,t,cnt); } cout<<ans<<endl; }