zoukankan      html  css  js  c++  java
  • POJ 2464 Brownie Points II(扫描线 + 两棵线段树 区间求和)

    题意:

    stan 划了一条竖线,ollie在这条线的基础上划一条横线,使自己能拿到的蛋糕尽可能的多。

    思路:

    1. 对于 y 坐标离散化,扫描线是垂直 x 轴的,从左向右:首先对 rtree 存放所有蛋糕,ltree 存放扫描线左边的蛋糕数,于是初始置 0

    2. 假设离散化后 y 的点数有 m 个,代码中为了方便 query 操作,区间是 [0, m],每个线段树节点代表 y 坐标范围内的个数。

    3. 因为题目中说了,x 坐标的点可能会重合,针对这种情况要特殊化考虑,多设置个 s 指针, 代码中 [s, i) 表示重合 x 坐标区间。

    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    #define lhs l, m, rt << 1
    #define rhs m + 1, r, rt << 1 | 1
    
    const int maxn = 200010;
    
    typedef struct _Point {
        int x, y;
        bool operator < (const _Point& other)
        { return x < other.x; }
    } Coord ;
    
    class CSegTree
    {
    private:
        int sum[maxn << 2];
    public:
        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(lhs);
            build(rhs);
        }
        void update(int p, int value, int l, int r, int rt)
        {
            if (l == r)
            {
                sum[rt] += value;
                return ;
            }
            int m = (l + r) >> 1;
            if (p <= m)
                update(p, value, lhs);
            else
                update(p, value, rhs);
            pushUp(rt);
        }
        int query(int beg, int end, int l, int r, int rt)
        {
            if (beg <= l && r <= end)
                return sum[rt];
            int m = (l + r) >> 1;
            int ret = 0;
            if (beg <= m)
                ret += query(beg, end, lhs);
            if (end > m)
                ret += query(beg, end, rhs);
            return ret;
        }
    };
    
    CSegTree ltree, rtree;
    Coord cord[maxn];
    int ycord[maxn];
    
    int binSearch(int value, int arr[], int size)
    {
        return lower_bound(arr, arr + size, value) - arr;
    }
    
    int main()
    {
        int n;
        while (scanf("%d", &n) && n)
        {
            for (int i = 0; i < n; ++i)
            {
                scanf("%d %d", &cord[i].x, &cord[i].y);
                ycord[i+1] = cord[i].y;
            }
            sort(ycord + 1, ycord + n + 1);
            sort(cord, cord + n);
    
            int m = unique(ycord + 1, ycord + n + 1) - (ycord + 1);
    
            ltree.build(0, m, 1);
            rtree.build(0, m, 1);
    
            int p;
            for (int i = 0; i < n; ++i)
            {
                p = binSearch(cord[i].y, ycord + 1, m) + 1;
                rtree.update(p, 1, 0, m, 1);
            }
    
            int best = 0;
            vector<int> ret;
            for (int i = 1, s = 0; i <= n; ++i)
            {
                if (i == n || cord[i].x != cord[i-1].x)
                {
                    for (int j = s; j < i; ++j)
                    {
                        p = binSearch(cord[j].y, ycord + 1, m) + 1;
                        rtree.update(p, -1, 0, m, 1);
                    }
    
                    int ollie = -1, stan = -1;
                    for (int j = s; j < i; ++j)
                    {
                        p = binSearch(cord[j].y, ycord + 1, m) + 1;
                        int a = ltree.query(0, p - 1, 0, m, 1) + rtree.query(p + 1, m, 0, m, 1);
                        int b = rtree.query(0, p - 1, 0, m, 1) + ltree.query(p + 1, m, 0, m, 1);
    
                        if (ollie == b)
                            stan = min(stan, a);
                        else if (ollie < b)
                            ollie = b, stan = a;
                    }
                    if (stan == best)
                        ret.push_back(ollie);
                    else if (stan > best)
                        best = stan, ret.clear(), ret.push_back(ollie);
                    
                    for (int j = s; j < i; ++j)
                    {
                        p = binSearch(cord[j].y, ycord + 1, m) + 1;
                        ltree.update(p, 1, 0, m, 1);
                    }
    
                    s = i;
                }
            }
            sort(ret.begin(), ret.end());
    
            printf("Stan: %d; Ollie:", best);
    
            for (int i = 0; i < ret.size(); ++i)
                if (i == 0 || ret[i] != ret[i-1])
                    printf(" %d", ret[i]);
            
            printf(";\n");
        }
        return 0;
    }
  • 相关阅读:
    node
    github
    [模块] pdf转图片-pdf2image
    python 15 自定义模块 随机数 时间模块
    python 14 装饰器
    python 13 内置函数II 匿名函数 闭包
    python 12 生成器 列表推导式 内置函数I
    python 11 函数名 迭代器
    python 10 形参角度 名称空间 加载顺序
    python 09 函数参数初识
  • 原文地址:https://www.cnblogs.com/kedebug/p/2891098.html
Copyright © 2011-2022 走看看