//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; }