题目链接
http://poj.org/problem?id=2182
题目大意说起来挺麻烦的,不说了。
唯一一个能看懂的题解
https://www.cnblogs.com/wzj-xhjbk/p/9737282.html
我就直接讲代码了
AC代码
#include<iostream> #define ll long long #define x first #define y second const int inf=0x3f3f3f3f; using namespace std; const int N=1e4; int c[N],a[N],ans[N],n; inline int lowbit(int x) { return x&(-x); } int getsum(int x) { int sum=0; while(x) { sum+=c[x]; x-=lowbit(x); } return sum; } void update(int x,int add) { while(x<=n) { c[x]+=add; x+=lowbit(x); } } int main() { cin>>n; a[1]=0; for(int i=2;i<=n;i++) { cin>>a[i]; } for(int i=n;i>=1;i--) { int l=0,r=n,pos; while(l<=r) { int mid=(l+r)>>1; if(mid>=a[i]+getsum(mid)+1) //mid是我们假设插入的位置,a[i]为比当前我们处理的这头牛编号小且在该牛前面的牛的数量(说白了就是题目让输入的!);getsum(mid)求得的是在当前我们处理的这头牛之前,已经插入在mid位置之前的牛有几头(这些已经插入的牛的编号都比当前牛的大)//我写的好长,你自己复制下来调整一下长度看吧,我懒得改了。 r=mid-1,pos=mid; else l=mid+1; } update(pos,1);//二分得到的插入位置,进行标记(比较抽象,需要好好理解) ans[i]=pos;//编号为i的牛的位置。 } for(int i=1;i<=n;i++) cout<<ans[i]<<endl; }