CSU 1553 线段树+尺取法

来源:互联网 发布:泛雅网络教学平台页面 编辑:程序博客网 时间:2024/05/21 21:36

G - G
Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%lld & %llu
Submit Status Practice CSU 1553

Description

Give you a sequence of n numbers, and a number k you should find the max length of Good subsequence. Good subsequence is a continuous subsequence of the given sequence and its maximum value - minimum value<=k. For example n=5, k=2, the sequence ={5, 4, 2, 3, 1}. The answer is 3, the good subsequence are {4, 2, 3} or {2, 3, 1}.

Input

There are several test cases.
Each test case contains two line. the first line are two numbers indicates n and k (1<=n<=10,000, 1<=k<=1,000,000,000). The second line give the sequence of n numbers a[i] (1<=i<=n, 1<=a[i]<=1,000,000,000). 
The input will finish with the end of file.

Output

For each the case, output one integer indicates the answer.

Sample Input

5 25 4 2 3 11 11

Sample Output

31



题意:给你n个数字,求出最长的一段数字使得(最大值-最小值)<=K


题解:线段树维护区间最值,尺取法枚举区间。复杂度O(N*logN)


#include <iostream>#include <cstring>#include<cstdio>#include<algorithm>using namespace std;#define LL long long#define N 20000#define inf 0x3f3f3f3fLL ma,mi;struct point{int lc,rc;LL max;LL min;}tree[N<<2];LL max(LL x,LL y){return x>y?x:y;}LL min(LL x,LL y){return x<y?x:y;}void Pushup(int rt){tree[rt].max=max(tree[rt<<1].max,tree[rt<<1|1].max);tree[rt].min=min(tree[rt<<1].min,tree[rt<<1|1].min);}void build(int L,int R,int rt){tree[rt].lc=L;tree[rt].rc=R;if(L==R){scanf("%lld",&tree[rt].max);tree[rt].min=tree[rt].max;return ;}int mid=(L+R)>>1;build(L,mid,rt<<1);build(mid+1,R,rt<<1|1);Pushup(rt);}void query(int L,int R,int rt){if(L==tree[rt].lc&&R==tree[rt].rc){ma=max(ma,tree[rt].max);mi=min(mi,tree[rt].min);return ;}int mid=(tree[rt].lc+tree[rt].rc)>>1;if(R<=mid)query(L,R,rt<<1);else if(L>mid)query(L,R,rt<<1|1);else{query(L,mid,rt<<1);query(mid+1,R,rt<<1|1);}}int main(){#ifdef CDZSCfreopen("i.txt","r",stdin);#endifint n;LL k;while(~scanf("%d%lld",&n,&k)){build(1,n,1);int ll=1,rr=1;int ans=-inf;while(ll<=n&&rr<=n){ma=-inf;mi=inf;query(ll,rr,1);if(ma-mi>k){while(ma-mi>k){ll++;ma=-inf;mi=inf;query(ll,rr,1);ans=max(ans,(rr-ll+1));}}else{ans=max(ans,(rr-ll+1));}rr++;}printf("%d\n",ans);}return 0;}









0 0