描述:
N(2<=N<=8,000)奶牛有独特的品牌在范围1.N.在一个糟糕的判断力的壮观显示,他们去附近的‘水坑’,并喝了太多啤酒在晚餐前。当是时候排队为他们的晚餐,他们没有排队按照所需的上升数字的顺序,他们的品牌。
令人遗憾的是,FJ没有办法解决这些问题。此外,他不太擅长观察问题。他没有写下每头牛的品牌,而是确定了一个相当愚蠢的统计数据:每一头排在奶牛前面的奶牛,他知道排在那头牛前面的奶牛的数量,事实上,这些奶牛的品牌比那头牛要小。
根据这些数据,告诉FJ奶牛的确切顺序。输入
*第1行:单个整数,N
*第2行.N:这些N1线描述的是排在一头母牛前面的奶牛的数量,并有比那头牛更小的品牌。当然,没有奶牛排在第一头牛的前面,所以她没有被列在名单上。输入的第2行描述在槽#2中品牌小于牛的前面奶牛的数量;第3行描述品牌小于槽#3中的牛的前面奶牛的数量,以此类推。输出量
*第1行.N:每一行输出的N条都告诉奶牛的品牌。输出的第1行告诉第一头奶牛的品牌,第2行告诉第二头奶牛的品牌,依此类推。
样本输入
5 1 2 1 0样本输出
2 4 5 3 1
1:不知为何,其他人说的树状数组是用找0的个数,根据我自几的理解,就是从后面的位置一次向前遍历,找到对应位置的牛的编号,在树状数组里,某一编号下的数值是1,说明该编号的牛还没有被安放下,否则为0;
2:根据牛前面有k个小于它的牛,用二分查询,具体看代码
树状数组+二分:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
ll c[10000],temp[10000],pa[10000];
ll n;
ll lowbit(ll x){
return x&(-x);
}
ll update(ll pos,ll cnt){
while(pos<=n){
c[pos]+=cnt;
pos+=lowbit(pos);
}
}
ll getsum(ll pos){
ll sum=0;
while(pos>0){
sum+=c[pos];
pos-=lowbit(pos);
}
return sum;
}
//二分查找牛的编号
ll find(ll cnt){//找第cnt个有效的1
ll l=1,r=n;
while(l<=r){
ll mid=(l+r)>>1;
ll num=getsum(mid);//前面有num头比编号该牛小的
if(num<cnt){//
l=mid+1;//说明l需要扩大
}
else if(num>=cnt)//说明r需要缩小
r=mid-1;
}
return l;
}
int main(){
scanf("%lld",&n);
for(ll i=1;i<=n;i++){
update(i,1);//初始化树状数组
}
for(ll i=2;i<=n;i++){
scanf("%lld",pa+i);
}
for(ll i=n;i>=1;i--){
ll pos=find(pa[i]+1);//找第pa[i]+1个有效1
update(pos,-1);//该位置牛被安放,置0
temp[i]=pos;
}
for(ll i=1;i<=n;i++){
printf("%lld\n",temp[i]);
}
return 0;
}
暴力:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
vector<ll> p;
ll stack[9000];
int main(){
ll n;
cin>>n;
for(ll i=1;i<=n;i++){
p.push_back(i);//1~n顺序存储
}
ll cnt;
for(cnt=1;cnt<n;cnt++){
cin>>stack[cnt];
}
ll a[9000];
ll mm=0;
for(cnt--;cnt>=1;cnt--){//寻找牛从后往前找
a[++mm]=p[stack[cnt]];//如果在剩下的牛中有k个比其小的,该牛其实就是p[k];
p.erase(p.begin()+stack[cnt]);//找到该位置的牛,将其移除
}
a[++mm]=p[0];//第一个位置的牛
p.pop_back();
for(;mm>0;mm--){
cout<<a[mm]<<endl;
}
return 0;
}