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;
    }
  • 相关阅读:
    commonjs
    基于webpack的vue开发环境搭建
    vs工程配置eslint检测环境
    h5笔记
    NPM install -save 和 -save-dev 区别
    小的div在大的div中垂直居中
    css position absolute相对于父元素的设置方式
    Python的支持工具[0] -> 环境包管理工具[1] -> Anaconda
    Python的支持工具[0] -> 环境包管理工具[0] -> pip
    代码编辑器[0] -> Vim/gVim[2] -> Vim 的相关知识
  • 原文地址:https://www.cnblogs.com/kedebug/p/2891098.html
Copyright © 2011-2022 走看看