有n头奶牛,已知它们的身高为 1~n 且各不相同,但不知道每头奶牛的具体身高。

现在这n头奶牛站成一列,已知第i头牛前面有Ai头牛比它低,求每头奶牛的身高。

输入格式
第1行:输入整数n。

第2…n行:每行输入一个整数Ai,第i行表示第i头牛前面有Ai头牛比它低。
(注意:因为第1头牛前面没有牛,所以并没有将它列出)

输出格式
输出包含n行,每行输出一个整数表示牛的身高。

第i行输出第i头牛的身高。

数据范围
1≤n≤105
输入样例:
5
1
2
1
0
输出样例:
2
4
5
3
1


很像一次cf的div2第四题。但是那道题是小于的每个数字的和。

做法:我们每次找到最后面的一个0,然后让这个位置后面的全部都减一,最后我们要删除当前的数字,就直接赋值为inf即可。


AC代码;

#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10,inf=0x3f3f3f3f;
int n,cnt,res[N];
struct node{
	int l,r,mi,add;
}t[N<<2];
inline void push_up(int p){
	t[p].mi=min(t[p<<1].mi,t[p<<1|1].mi);
}
inline void push_down(int p){
	if(t[p].add){
		t[p<<1].mi-=t[p].add; t[p<<1|1].mi-=t[p].add;
		t[p<<1].add+=t[p].add; t[p<<1|1].add+=t[p].add;
		t[p].add=0;
	}
}
void build(int p,int l,int r){
	t[p].l=l; t[p].r=r;
	if(l==r){
		if(cnt)	scanf("%d",&t[p].mi); cnt++; return ;
	}
	int mid=l+r>>1;
	build(p<<1,l,mid);	build(p<<1|1,mid+1,r);
	push_up(p);
}
void change(int p,int l,int r){
	if(t[p].l==l&&t[p].r==r){
		t[p].mi-=1; t[p].add+=1; return ;
	}
	push_down(p); int mid=t[p].l+t[p].r>>1;
	if(r<=mid)	change(p<<1,l,r);
	else if(l>mid)	change(p<<1|1,l,r);
	else	change(p<<1,l,mid),change(p<<1|1,mid+1,r);
	push_up(p);
}
void updata(int p,int x){
	if(t[p].l==t[p].r){
		t[p].mi=inf;	return ;
	}
	push_down(p);	int mid=t[p].l+t[p].r>>1;
	if(x<=mid)	updata(p<<1,x);
	else	updata(p<<1|1,x);
	push_up(p);
}
int ask(int p){
	if(t[p].l==t[p].r)	return t[p].l;
	push_down(p); int mid=t[p].l+t[p].r>>1;
	if(!t[p<<1|1].mi)	return ask(p<<1|1);
	else return ask(p<<1);
}
signed main(){
	cin>>n;	build(1,1,n);
	for(int i=1;i<=n;i++){
		int x=ask(1); res[x]=i; updata(1,x);
		if(x!=n)	change(1,x+1,n);
	}
	for(int i=1;i<=n;i++)	printf("%d\n",res[i]);
	return 0;
}