逆向考虑 O(N)复杂度。

因为每个点都在 [1,n] 范围上,所以用数组模拟双向链表即可,数据再大就配合map。

#include <bits/stdc++.h>
using namespace std;

int tem[200010],num[200010],pre[200010],nxt[200010];
int n,k,a,m;

int main()
{
int i,cnt,v1,v2;
while(scanf("%d%d%d",&n,&k,&a)!=EOF)
{
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d",&tem[i]);
num[i]=tem[i];
}
num[0]=0,num[m+1]=n+1;
sort(num,num+m+2);
for(i=1;i<=m;i++)
{
pre[num[i]]=num[i-1];
nxt[num[i]]=num[i+1];
}
pre[0]=-1,nxt[n+1]=-1;
cnt=0;
for(i=1;i<=m+1;i++)
{
cnt+=(num[i]-num[i-1])/(a+1);
}
if(cnt>=k)
{
printf("-1\n");
continue;
}
for(i=m;i>=1;i--)
{
v1=(nxt[tem[i]]-pre[tem[i]])/(a+1);
v2=(nxt[tem[i]]-tem[i])/(a+1)+(tem[i]-pre[tem[i]])/(a+1);
if(v1>v2) cnt++;
nxt[pre[tem[i]]]=nxt[tem[i]];
pre[nxt[tem[i]]]=pre[tem[i]];
if(cnt==k)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}