Jzoj P6310 Global warming___思維+枚舉+LIS

題目大意:

給定整數 n 和 x,以及一個大小爲 n 的序列 a。
你可以選擇一個區間 [l,r],然後令 a[i]+=d(l<=i<=r),其中 d 滿足 |d|<=x。
要求最大化 a 的最長上升子序列的長度,並輸出該值
n<=200000,x<=10^9

分析:

在這裏插入圖片描述

代碼:

#pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>

#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)

#define N 200005

using namespace std;

struct Node {
	int id, num, rmax;
}C[N];
int f1[N], f2[N], dp[N], a[N], n, m, top, ans;

void read(int &x) {
	int f = 1; x = 0; char s = getchar();
	while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
	while (s >= '0' && s <= '9') { x = x * 10 + (s - '0'); s = getchar(); }
	x = x * f;	
}

int main() {
	freopen("glo.in", "r", stdin);
	freopen("glo.out", "w", stdout);
	read(n); read(m);
	rep(i, 1, n) read(a[i]); 
    f1[1] = 1; dp[++top] = a[1];
	rep(i, 2, n) {
		if (a[i] > dp[top]) {
		    dp[++top] = a[i]; 
	        f1[i] = top;
		}
		else 
		if (a[i] + m > dp[top]) {
            f1[i] = top + 1;
		    int id = lower_bound(dp + 1, dp + top + 1, a[i]) - dp;
		    dp[id] = a[i];
		} else {
			f1[i] = lower_bound(dp + 1, dp + top + 1, a[i] + m) - dp;
			int id = lower_bound(dp + 1, dp + top + 1, a[i]) - dp;
			dp[id] = a[i]; 
		}
	}
	f2[n] = 1; dp[top = 1] = -a[n];
	rwp(i, n - 1, 1) {
		if (-a[i] > dp[top]) {
		    dp[++top] = -a[i]; 
	        f2[i] = top;
		}
		else {
			int id = lower_bound(dp + 1, dp + top + 1, -a[i]) - dp;
			f2[i] = id;
			dp[id] = -a[i]; 
		}		
	}
	rep(i, 1, n) ans = max(ans, f1[i] + f2[i] - 1); 
	printf("%d\n", ans);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章