E. Pencils and Boxes(尺取&dp)

显然按val排序,然后考虑dp,显然转移的 j j j i i i增加不会递减,接着考虑限制条件,显然i往右走,要是差值小于d,i递增, 因为有k的限制。

所以每次转移的时候是找一个区间是否可行,找区间是否有解可用BIT,线段树,ST等。初始化 d p 0 = 1 dp_0=1 dp0=1,所以BIT整体右移下即可。

// Problem: E. Pencils and Boxes
// Contest: Codeforces - Educational Codeforces Round 44 (Rated for Div. 2)
// URL: https://codeforces.ml/contest/985/problem/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Date: 2021-07-31 09:36:59
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=5e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define IOS ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\n",a[n]); 
}
#define lowbit(x) x&(-x)
int f[N],n,k,d,a[N];
bool dp[N];
void upd(int x,int v){
	while(x<=n+1) f[x]+=v,x+=lowbit(x);
}
int que(int x){
	int s=0;
	while(x) s+=f[x],x-=lowbit(x);return s;
}
int que(int l,int r){
	if(l>r) return 0;
	l++,r++;
	return que(r)-que(l-1);
}
int main(){
	scanf("%d%d%d",&n,&k,&d);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);sort(a+1,a+n+1);
	dp[0]=1;
	upd(1,1);
	for(int i=1,l=0;i<=n;i++){
		while(a[i]-a[l+1]>d) l++;
		dp[i]=(que(l,i-k)>=1);
		if(dp[i]) upd(i+1,1);
	}
	puts(dp[n]?"YES":"NO");
	return 0;
}