Lost Cows --线段树点修改

 

题目大意:有编号为1~n的n头牛,已知排在第i头牛前面且比第i头牛编号小的牛的数量为ai,求第i头牛的编号

Input:   c组数据,每组数组一个n,接着n个数字表示排在第i位的牛的ai.

Output:  按顺序输出每位牛的编号.

思路:

从最后一头牛开始,ans[i]=剩余编号中的第ai小的编号,

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=10000;
struct node{
    int l,r,val,sum;
};
int n;
node tree[maxn<<2];
int a[maxn],ans[maxn];
bool mark[maxn];
void build(int root,int l,int r){
     if(l==r){
        tree[root].l=r,tree[root].r=r,tree[root].val=l;tree[root].sum=1;
        return ;
     }
     int mid=(l+r)>>1;
     tree[root].l=l,tree[root].r=r,tree[root].sum=r-l+1;
     if(mid>=l)build(root<<1,l,mid);
     if(mid<r)build(root<<1|1,mid+1,r);
}
int query(int root,int x){
    int ans;
     if(tree[root].l==tree[root].r){
        tree[root].sum--;
        mark[tree[root].val]=false;
        return tree[root].val;
     }
     if(tree[root<<1].sum<x)ans=query(root<<1|1,x-tree[root<<1].sum);
     else ans=query(root<<1,x);
     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
     return ans;
}
int main(){
     while(~scanf("%d",&n)){
         memset(mark,true,sizeof(mark));
         for(int i=1;i<n;i++)
            scanf("%d",&a[i]);
        build(1,1,n);
        for(int i=n-1;i>0;i--){
            ans[i]=query(1,a[i]+1);
        }
        for(int i=1;i<=n;i++)if(mark[i]){ans[0]=i;break;}
        for(int i=0;i<n;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

 

posted @ 2020-09-13 21:43  十分的月亮  阅读(155)  评论(0)    收藏  举报