线段树单点插入。弄一个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;
}