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

浙公网安备 33010602011771号