题目链接:https://nanti.jisuanke.com/t/41303
签到题。
对于每一个数,假设它的位置为pos,则ans[i]=ans[max{pos-k,pos+k}]+1,计算完ans后更新i。按数字大小转移即可。
例如样例中
7 2
3 1 4 6 2 5 7
从1至7更新
a 1
ans 0 1 0 0 0 0 0
p 1 1 1 1 0 0 0
a 1 2
ans 0 1 0 0 1 0 0
p 1 1 2 2 2 2 2
a 3 1 2
ans 2 1 0 0 1 0 0
p 3 3 3 2 2 2 2
a 3 1 4 2
ans 2 1 3 0 1 0 0
p 4 4 4 4 4 2 2
a 3 1 4 2 5
ans 2 1 3 0 1 2 0
p 4 4 4 5 5 5 5
a 3 1 4 6 2 5
ans 2 1 3 3 1 2 0
p 4 6 6 6 6 6 5
a 3 1 4 6 2 5 7
ans 2 1 3 3 1 2 3
p 4 6 6 6 7 7 7
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define maxn 400050
#define INF 0x3f3f3f
#define ll long long
#define cin(x) scanf("%d",&x)
#define cout(x) printf("%d ",x)
ll T,n,m,k,a[maxn],b[maxn];
struct nodes{
int num,val;
}s[maxn];
struct a{
ll l,r,max;
}tree[maxn];
ll ans[maxn];
void build_tree(ll x,ll l,ll r){
tree[x].l=l;
tree[x].r=r;
if(l==r){
tree[x].max=0;
return;
}
build_tree(x*2,l,(l+r)/2);
build_tree(x*2+1,(l+r)/2+1,r);
tree[x].max=0;
}
void update(ll x,ll l,ll r,ll k){
if(tree[x].l>=l&&tree[x].r<=r){
tree[x].max=k;
return;
}
if(tree[x].l>r||tree[x].r<l) return;
update(x*2,l,r,k);
update(x*2+1,l,r,k);
}
ll query(ll x,ll pos){
if(tree[x].l==tree[x].r){
return tree[x].max;
}
if(tree[x].l==tree[x].r) return 0;
ll mid=(tree[x].l+tree[x].r)>>1;
if(pos<=mid) return max(tree[x].max,query(x<<1,pos));
else return max(tree[x].max,query(x<<1|1,pos));
}
int cmp(nodes s1,nodes s2){
return s1.val<s2.val;
}
int main(){
cin(T);
while(T--){
cin(n),cin(k);
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++){
cin(s[i].val);
s[i].num=i;
}
sort(s+1,s+1+n,cmp);
build_tree(1,1,n);
for(int i=1;i<=n;i++){
ll pos=s[i].num;//cout(pos);
ans[i]=ans[query(1,pos)]+1;
update(1,max(1ll,pos-k),min(n,pos+k),i);
}
for(int i=1;i<=n;i++){
if(i!=n) cout(ans[i]);
else printf("%lld",ans[i]);
}
cout<<endl;
}
return 0;
}