Lost Cows(线段树+二分判定)

4835: [Usaco2003 Open]Lost Cows

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 21  Solved: 17
[Submit][Status][Web Board]

Description

N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judg

ment, they visited the neighborhood ‘watering hole‘ and drank a few too many beers before dinner. Wh

en it was time to line up for their evening meal, they did not line up in the required ascending num

erical order of their brands.Regrettably, FJ does not have a way to sort them. Furthermore, he‘s not

very good at observing problems. Instead of writing down each cow‘s brand, he determined a rather s

illy statistic: For each cow in line, he knows the number of cows that precede that cow in line that

do, in fact, have smaller brands than that cow.Given this data, tell FJ the exact ordering of the c

ows.

1~n,乱序排列,告诉每个位置的前面的数字中比它小的数的个数,求每个位置的数字是多少

Input

* Line 1: A single integer, N

* Lines 2..N: These N-1 lines describe the number of cows that precede a given cow in line and have

brands smaller than that cow. Of course, no cows precede the first cow in line, so she is not listed

. Line 2 of the input describes the number of preceding cows whose brands are smaller than the cow i

n slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in sl

ot #3; and so on.

Output

* Lines 1..N: Each of the N lines of output tells the brand of a cow in line.

Line #1 of the output tells the brand of the first cow in line;

line 2 tells the brand of the second cow; and so on.

Sample Input

5
1
2
1
0 

Sample Output

2
4
5
3
1 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn=8000+10;

int tree[maxn<<2];
int a[maxn],n;
int ans[maxn];

void pushup(int x){
     tree[x]=tree[x<<1]+tree[x<<1|1];
}

void change(int l,int r,int rt,int R,int c){
     if(l==r) {
        tree[rt]+=c;
        return ;
     }
     int mid=(l+r)>>1;
     if(R<=mid) change(l,mid,rt<<1,R,c);
     else change(mid+1,r,rt<<1|1,R,c);
     pushup(rt);
}

int ask(int l,int r,int rt,int L,int R){
    if(l>=L&&r<=R) return tree[rt];
    int mid=(l+r)>>1;
    int ans=0;
    if(L<=mid) ans+=ask(l,mid,rt<<1,L,R);
    if(R>mid) ans+=ask(mid+1,r,rt<<1|1,L,R);
    return ans;
}

int solve(int x){
    int l=1,r=n;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(ask(1,n,1,1,mid)<x)
            l=mid+1;
        else r=mid-1;
    }
    return l;
}

void build(int l,int r,int rt){
     if(l==r){
        tree[rt]=1;
        return ;
     }
     int mid=(l+r)>>1;
     build(l,mid,rt<<1);
     build(mid+1,r,rt<<1|1);
    pushup(rt);
}

int main(){
    scanf("%d",&n);
    for (int i=2;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int top=0;
    build(1,n,1);
    for (int i=n;i>=1;i--){
        ans[i]=solve(a[i]+1);
        change(1,n,1,ans[i],-1);
    }
    for (int i=1;i<=n;i++) printf("%d\n",ans[i]);
 return 0;
}

原文地址:https://www.cnblogs.com/lmjer/p/9194976.html

时间: 2024-10-21 22:26:57

Lost Cows(线段树+二分判定)的相关文章

POJ 2481 Cows (线段树)

Cows 题目:http://poj.org/problem?id=2481 题意:有N头牛,每只牛有一个值[S,E],如果对于牛i和牛j来说,它们的值满足下面的条件则证明牛i比牛j强壮:Si <=Sjand Ej <= Ei and Ei - Si > Ej - Sj.现在已知每一头牛的测验值,要求输出每头牛有几头牛比其强壮. 思路:将牛按照S从小到大排序,S相同按照E从大到小排序,这就保证了排在后面的牛一定不比前面的牛强壮.再按照E值(离散化后)建立一颗线段树(这里最值只有1e5,所

hdu 4893 (多校1007)Wow! Such Sequence!(线段树&amp;二分&amp;思维)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 352    Accepted Submission(s): 104 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

POJ 2182 Lost Cows.(线段树)

~~~~ 数据太水,暴力无压力,不过还是用线段树写了下,表现了楼主对线段树的无限热爱之情. ~~~~ 题目连接:http://poj.org/problem?id=2182 大致题意;牛牛因XXXXXX原因乱序成一排,现已知每头牛前面有多少头牛比它的编号小(第一头牛前面没有当然就不列粗来了),求每头牛的编号. 思路:从后往前扫描,遇到a,则说明它是剩余序列的第a+1头牛. ~~~~ 暴力代码:(157ms) #include<cstdio> #include<algorithm>

hdu 5592 ZYB&#39;s Premutation (线段树+二分查找)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=5592 Problem Description ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ask you to  restore the premutation.Pair (i,j)(i<j) is considered as a reverse

poj 2182 Lost Cows(线段树经典题)

题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9152   Accepted: 5879 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, th

Educational Codeforces Round 64 (Rated for Div. 2) (线段树二分)

题目:http://codeforces.com/contest/1156/problem/E 题意:给你1-n  n个数,然后求有多少个区间[l,r] 满足    a[l]+a[r]=max([l,r]) 思路:首先我们去枚举区间肯定不现实,我们只能取把能用的区间去用,我们可以想下每个数当最大值的时候所做的贡献 我们既然要保证这个数为区间里的最大值,我们就要从两边扩展,找到左右边界能扩展在哪里,这里你直接去枚举肯定不行 这里我们使用了线段树二分去枚举左右区间最远能走到哪里,然后很暴力的去枚举短

codeforces 589G:线段树+二分

离线做 先按照t[]建线段树,维护区间的有效天数以及可用时间 然后把t[]从小到达排序,记得记录t中元素在线段树中的位置 把询问按照d从小到大排序,依次考虑 由于按照d排序,所以当前询问肯定是d最短的,我们在t数组中找到大于当前d的第一个元素位置,把这之前的元素全部从线段树中删除,表示这些天数无效 因为当前d已经是最小,所以删除对后续不会有影响 二分一个天数,查找0~mid天一共的工作时间(工作时间=总可用时间-准备时间*有效天数) #include"cstdio" #include&

codeforces 487B B. Strip(rmq+线段树+二分)

题目链接: codeforces 487B 题目大意: 给出一个序列,要把序列划分成段,每一段最少有L个元素,段中的最大元素和最小元素之差不大于s,问划分的段的最少的数量是多少. 题目分析: 首先用rmq维护区间最大值和区间最小值. 然后按顺序扫描数组,线段树维护的数组,每个记录当前点作为最后一个点的前i个点划分的最小的段数,那么每次更新就是二分找到可以转移到我的最远距离,然后再选取与我距离大于l的那部分,取最小值即可. 最终结果就是线段树维护的数组的最后一个位置的元素的值. AC代码: #in

hdu 6070 线段树+二分

HDU - 6070 题意:提交了n次题目,每个题目都是最后一次提交的时候AC的,现在求一个区间,这个区间的AC率是最低的(只考虑这个区间内的题目,同样区间内最后交的一遍是AC的),求最低的AC率 思路:AC率=提交次数/题目数目,即区间长度/题目种类,siz[l,r]/(r-l+1)=p(siz[l,r]表示l r区间内的不同题目的个数,p表示AC率), 把式子做一下调整,siz[l,r]+p*l=p(r+1),二分p(0-1)用线段树维护siz[l,r]+l*p ,然后枚举r,每次更新,因为