线段树单点插入。弄一个pre数组记录该点能达到的最大上升序列值(不包括该点),遍历1到n,插入一个点,查询更新第i+d+1个点的pre。。

#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <climits>
#define maxn 100005
#define eps 1e-6
#define mod 200000007
#define INF 99999999
#define lowbit(x) (x&(-x))
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
typedef long long LL;
using namespace std;

int maxv[maxn<<3];
int num[maxn];
int pre[maxn<<1];
int n, ql, qr;
int p, v, d;

void init(void)
{
	memset(maxv, 0, sizeof maxv);
	memset(pre, 0, sizeof pre);
}
int query(int o, int L, int R)
{
	if(ql<=L && qr>=R) return maxv[o];
	int mid=(R+L)>>1, ans=0;
	if(ql<=mid) ans=max(ans, query(lson));
	if(qr>mid) ans=max(ans, query(rson));
	return ans;
}
void pushup(int o)
{
	maxv[o]=max(maxv[o<<1], maxv[o<<1 | 1]);
}
void updata(int o, int L, int R)
{
	if(L==R){
		maxv[o]=v;
		return;
	}
	int mid=(R+L)>>1;
	if(p<=mid) updata(lson);
	else updata(rson);
	pushup(o);
}
void work(void)
{
	int i, tmp;
	for(i=1;i<=n;i++){
		scanf("%d",&num[i]);
		num[i]++;
	}
	for(i=1;i<=n;i++){
		ql=1, qr=num[i+d+1]-1;
		p=num[i], v=pre[i]+1;
		updata(1, 1, maxn);
		if(qr>=ql) tmp=query(1, 1, maxn);
		else tmp=0;
		pre[i+d+1]=tmp;
	}
	printf("%d\n", maxv[1]);
}
int main(void)
{
	while(scanf("%d%d", &n, &d)!=EOF){
		init();
		work();
	}
	return 0;
}