//CodeForces 91B Queue 线段树 单点更新 成段查询
/*
题目地址:http://codeforces.com/problemset/problem/91/B
题意:
有n个数的失望值,
失望值的定义是:离它最远的比它小的数 与 它本身之间 间隔的数的数量
思路:
线段树,结点保存区间最小值
每次将当前的数更新为INF,然后查找整个区间内最右边的比它小的数的下标
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INF 1000000005
#define N 100005
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
int mmin[N<<2],s[N];
int Min(int x,int y){
return x<y?x:y;
}
void Pushup(int rt){
mmin[rt] = Min(mmin[rt<<1],mmin[rt<<1|1]);
}
void Build(int rt,int l,int r){
if(l == r){
scanf("%d",&mmin[rt]);
s[l] = mmin[rt];
return ;
}
int mid = (l + r) >> 1;
Build(lson);
Build(rson);
Pushup(rt);
}
void Update(int rt,int l,int r,int x){
if(l == r){
mmin[rt] = INF;
return ;
}
int mid = (l + r) >> 1;
if(x <= mid) Update(lson,x);
else Update(rson,x);
Pushup(rt);
}
int Query(int rt,int l,int r,int x){
if(l == r)
return l;
int mid = (l + r) >> 1;
if(mmin[rt<<1|1] < x) return Query(rson,x);
else return Query(lson,x);
}
int main(){
int n,i;
while(scanf("%d",&n)!=EOF){
Build(1,1,n);
for(i = 1; i <= n; ++i){
Update(1,1,n,i);
if(mmin[1] >= s[i])
printf("%d%c",-1,i==n?'\n':' ');
else
printf("%d%c",Query(1,1,n,s[i])-i-1,i==n?'\n':' ');
}
}
return 0;
}
CodeForces 91B Queue 线段树 单点更新 成段查询
最新推荐文章于 2021-06-30 16:37:26 发布