1. 程式人生 > >POJ 2481 Cows (線段樹)

POJ 2481 Cows (線段樹)

max lan rgb query deb ons stack rep memset

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,所以不用離散化也行)。遍歷每一頭牛,在它之前的。E值大於它的牛的數目即是答案(要註意兩者同樣的情況)。

事實上,上面的線段樹就是排序好之後的E值序列的中每個數的逆序對數目。
代碼:
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<fstream>
#include<cstring>
#include<ctype.h>
#include<iostream>
#include<algorithm>
#define INF (1<<30)
#define PI acos(-1.0)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, n) for (int i = 0; i < n; i++)
#define debug puts("===============")
typedef long long ll;
using namespace std;
const int maxn = 100100;
int n;
struct node {
    int x, y, id;
}e[maxn];
bool cmp(node s, node v) {
    if (s.x == v.x) return s.y > v.y;
    return s.x < v.x;
}
int x[maxn], index[maxn], dis[maxn];
int discrete(int x[], int index[], int dis[], int n) {
    int cpy[n];
    for (int i = 0; i < n; i++) {
        x[i] = e[i].y;
        cpy[i] = x[i];
    }
    sort(cpy, cpy + n);
    int tot = unique(cpy, cpy + n) - cpy;
    for (int i = 0; i < n; i++) {
        dis[i] = lower_bound(cpy, cpy + tot, x[i]) - cpy;
        index[dis[i]] = i;
    }
    return tot;
}
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
int has[maxn];
int sum[maxn << 2];
void pushup(int rt) {
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void build(int l, int r, int rt) {
    sum[rt] = 0;
    if (l == r) return ;
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
}
void add(int pos, int x, int l, int r, int rt) {
    if (l == r) {
        sum[rt] += x;
        return ;
    }
    int m = (l + r) >> 1;
    if (pos <= m) add(pos, x, lson);
    else add(pos, x, rson);
    pushup(rt);
}
int query(int L, int R, int l, int r, int rt) {
    if (L <= l && r <= R) return sum[rt];
    int m = (l + r) >> 1;
    int res = 0;
    if (L <= m) res += query(L, R, lson);
    if (R > m) res += query(L, R, rson);
    return res;
}
int main () {
    while(~scanf("%d", &n), n) {
        for (int i = 0; i < n; i++) {
            scanf("%d%d", &e[i].x, &e[i].y);
            e[i].id = i;
        }
        sort(e, e + n, cmp);
        int m = discrete(x, index, dis, n);
        //rep(i, n) cout<<e[i].x<<" "<<e[i].y<<"-------->"<<e[i].id<<" "<<dis[i]<<endl;
        int nowx = -1, nowy = -1, ans = 0, cnt = 1;
        build(0, m - 1, 1);
        for (int i = 0; i < n; i++) {
            if (e[i].x == nowx && e[i].y == nowy) {
                has[e[i].id] = ans;
            } else {
                ans = query(dis[i], m - 1, 0, m - 1, 1);
                has[e[i].id] = ans;
                nowx = e[i].x, nowy = e[i].y;
            }
            add(dis[i], 1, 0, m - 1, 1);
        }
        for (int i = 0; i < n; i++) printf("%d%c", has[i], i == n - 1 ? ‘\n‘ : ‘ ‘);
    }
    return 0;
}


POJ 2481 Cows (線段樹)