BZOJ 5442: [Ceoi2018]Global warming

[l,r]+x不如[l,n]+x

[l,r]-x不如(r,n)+x

所以等价于只有[l,n]+x

枚举断点树状数组合并

难度在于想到这个贪心

#include<cstdio>
#include<algorithm>
using namespace std;
int cnt,n,x,A[1000005],stack[1000005],F[1000005],E[1000005],S[1000005],T[1000005],a[1000005],tree[1000005];
void solve(){
	int tail=0;
	stack[0]=-1e9;
	for (int i=1; i<=n; i++){
		if (A[i]>stack[tail]) {
			stack[++tail]=A[i];
			F[i]=tail;
		}
		else{
			int ID=lower_bound(stack+1,stack+tail+1,A[i])-stack;
			stack[ID]=A[i];
			F[i]=ID;
		}
	}
}
int lowbit(int x){
	return x&(-x);
}
void insert(int x,int y){
	for (int i=x; i<=cnt; i+=lowbit(i)) tree[i]=max(tree[i],y);
}
int query(int x){
	int ans=0;
	for (int i=x; i; i-=lowbit(i)) ans=max(ans,tree[i]);
	return ans;
}
int main(){
	scanf("%d%d",&n,&x);
	if (x<0) x=-x;
	for (int i=1; i<=n; i++) scanf("%d",&a[i]);
	for (int i=1; i<=n; i++) E[++cnt]=a[i];
	for (int i=1; i<=n; i++) E[++cnt]=a[i]+x-1;
	sort(E+1,E+cnt+1);
	cnt=unique(E+1,E+cnt+1)-E-1;
	for (int i=1; i<=n; i++) A[i]=a[i];
	solve();
	for (int i=1; i<=n; i++) S[i]=F[i];
	for (int i=1; i<=n/2; i++) swap(A[i],A[n-i+1]);
	for (int i=1; i<=n; i++) A[i]=-A[i];
	solve();
	for (int i=1; i<=n; i++) T[i]=F[n-i+1];
	int ans=0;
	for (int i=1; i<=n; i++){
		ans=max(ans,T[i]+query(lower_bound(E+1,E+cnt+1,a[i]+x-1)-E));
		insert(lower_bound(E+1,E+cnt+1,a[i])-E,S[i]);
	}
	printf("%d\n",ans);
	return 0;
}

  

posted @ 2018-10-22 19:37  ~Silent  阅读(206)  评论(0编辑  收藏  举报
Live2D