线段树/树状数组 POJ 2182 Lost Cows

题目传送门

题意:n头牛,1~n的id给它们乱序编号,已知每头牛前面有多少头牛的编号是比它小的,求原来乱序的编号

分析:从后往前考虑,最后一头牛a[i] = 0,那么它的编号为第a[i] + 1编号:为1,倒数第二头牛的编号为除去最后一头牛的编号后的第a[i-1] + 1编号:为3,其他的类推,所以可以维护之前已经选掉的编号,求第k大的数字,sum[rt] 表示该区间已经被选掉的点的个数。另外树状数组也可以做,只不过用二分优化查找第k大的位置。

收获:逆向思维,求动态第K大

代码(线段树):

/************************************************
* Author        :Running_Time
* Created Time  :2015/9/9 星期三 17:01:08
* File Name     :P.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 8e3 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
struct ST   {
    int sum[N<<2];
    void build(int l, int r, int rt)    {
        sum[rt] = 0;
        if (l == r) return ;
        int mid = (l + r) >> 1;
        build (lson);
        build (rson);
    }
    int query(int p, int l, int r, int rt)  {
        sum[rt]++;
        if (l == r) return l;
        int mid = (l + r) >> 1;
        int tmp = mid - l + 1 - sum[rt<<1];
        if (tmp >= p)    return query (p, lson);
        else    {
            return query (p - tmp, rson);
        }
    }
}st;
int a[N], ans[N];

int main(void)    {
    int n;
    while (scanf ("%d", &n) == 1)   {
        a[1] = 0;
        for (int i=2; i<=n; ++i) {
            scanf ("%d", &a[i]);
        }
        st.build (1, n, 1);
        for (int i=n; i>=1; --i)    {
            ans[i] = st.query (a[i] + 1, 1, n, 1);
        }
        for (int i=1; i<=n; ++i)    {
            printf ("%d\n", ans[i]);
        }
    }

    return 0;
}

  

代码(树状数组):

/************************************************
* Author        :Running_Time
* Created Time  :2015/9/9 星期三 18:19:28
* File Name     :P_BIT.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 8e3 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int n;
struct BIT  {
    int c[N];
    void init(void) {
        memset (c, 0, sizeof (c));
    }
    void updata(int i, int x)  {
        while (i <= n)   {
            c[i] += x;  i += i & (-i);
        }
    }
    int query(int i)    {
        int ret = 0;
        while (i)   {
            ret += c[i];    i -= i & (-i);
        }
        return ret;
    }
    int bsearch(int l, int r, int k)    {
        while (l <= r)  {
            int mid = (l + r) >> 1;
            if (mid - query (mid) >= k) r = mid - 1;
            else    l = mid + 1;
        }
        return l;
    }
}bit;
int a[N], ans[N];

int main(void)    {
    while (scanf ("%d", &n) == 1)   {
        a[1] = 0;
        for (int i=2; i<=n; ++i)    scanf ("%d", &a[i]);
        bit.init ();
        for (int i=n; i>=1; --i)    {
            ans[i] = bit.bsearch (1, n, a[i] + 1);
            bit.updata (ans[i], 1);
        }
        for (int i=1; i<=n; ++i)    {
            printf ("%d\n", ans[i]);
        }
    }

    return 0;
}

  

时间: 2024-08-04 18:35:47

线段树/树状数组 POJ 2182 Lost Cows的相关文章

poj 2182 Lost Cows (线段树)

 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8838   Accepted: 5657 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood 'wate

POJ 2182 Lost Cows.(线段树)

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

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

POJ 2182 Lost Cows (树状数组 &amp;&amp; 二分查找)

题意:给出数n, 代表有多少头牛, 这些牛的编号为1~n, 再给出含有n-1个数的序列, 每个序列的数 ai 代表前面还有多少头比 ai 编号要小的牛, 叫你根据上述信息还原出原始的牛的编号序列 分析:如果倒着看这个序列的话, 那序列的最后一个元素就能够确定一个编号.举个例子:如果序列的最后一个元素为0, 那就说明这头牛前面再也没有比它编号更小的牛了, 所以这头牛的编号肯定是最大的, 我们只要给它所在的编号加个标记, 然后继续根据倒数第二个.第三个--来依次确定便可还原整个序列, 这里可以使用树

POJ 2182 Lost Cows (树状数组)

Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9660   Accepted: 6219 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood 'waterin

线段树&amp;数状数组

线段树 单点修改,区间查询 #include<bits/stdc++.h> using namespace std; int n,q; long long num[1000010]; struct tree { int l,r; long long sum,max; }t[4000010]; void BuildTree(int,int,int); void Update(int,int,int,int,long long); long long Query(int,int,int,int,i

LCA+树状数组 POJ 2763 Housewife Wind

题目传送门 题意:两种操作,问u到v的距离,并且u走到了v:把第i条边距离改成w 分析:根据DFS访问顺序,将树处理成链状的,那么回边处理成负权值,那么LCA加上BIT能够知道u到v的距离,BIT存储每条边的信息,这样第二种操作也能用BIT快速解决 利用RMQ的写法不知哪里写挫了,改用倍增法 /************************************************ * Author :Running_Time * Created Time :2015/10/6 星期二

树状数组 POJ 2481 Cows

题目传送门 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int MAX_N = 100000 + 10; 7 int cnt[MAX_N]; 8 int ans[MAX_N]; 9 int maxn = -1; 10 struct node 11 { 12 int s, e; 13 int id; 14 }cow[MAX_

( 树状数组) poj 2029

Get Many Persimmon Trees Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3700   Accepted: 2405 Description Seiji Hayashi had been a professor of the Nisshinkan Samurai School in the domain of Aizu for a long time in the 18th century. In