首页 > 其他分享 >lc2250 统计包含每个点的矩形数目

lc2250 统计包含每个点的矩形数目

时间:2024-03-16 13:11:55浏览次数:23  
标签:node return int 数目 son lc2250 TYPE 矩形 data

有n个矩形,第i个矩形左下角在(0,0)处,右上角在(l[i],h[i])。另给出m个点(x[i],y[i]),问有多少个矩形覆盖了这个点,点在边上也算是覆盖。
1<=n,m<=5e4; 1<=l[i],h[i]<=1e9; 1<=h[i],y[i]<=100; 所有矩形互不相同,所有查询点互不相同。

二维偏序统计问题,可以离线处理,先对其中一维排序,将第一维可行的记录加到集合,然后在集合中查询第二维。

template <typename TYPE>
struct Treap {
    struct Node {
        TYPE data, sum;
        int rnd, siz, dup, son[2];
        void init(const TYPE & d) {
            data = sum = d;
            rnd = rand();
            siz = dup = 1;
            son[0] = son[1] = 0;
        }
    };
    Treap(size_t sz, bool multi):multiple(multi) {
        node.resize(sz);
        reset();
    }
    int newnode(const TYPE & d) {
        total += 1;
        node[total].init(d);
        return total;
    }
    void reset() { root = total = 0; }
    void maintain(int x) {
        node[x].siz = node[x].dup;
        node[x].sum = node[x].data * node[x].dup;
        if (node[x].son[0]) {
            node[x].siz += node[node[x].son[0]].siz;
            node[x].sum += node[node[x].son[0]].sum;
        }
        if (node[x].son[1]) {
            node[x].siz += node[node[x].son[1]].siz;
            node[x].sum += node[node[x].son[1]].sum;
        }
    }
    void rotate(int d, int &r) {
        int k = node[r].son[d^1];
        node[r].son[d^1] = node[k].son[d];
        node[k].son[d] = r;
        maintain(r);
        maintain(k);
        r = k;
    }
    void insert(const TYPE &data, int &r, bool &ans) {
        if (r) {
            if (!(data < node[r].data) && !(node[r].data < data)) {
                ans = false;
                if (multiple) {
                    node[r].dup += 1;
                    maintain(r);
                }
            } else {
                int d = data < node[r].data ? 0 : 1;
                insert(data, node[r].son[d], ans);
                if (node[node[r].son[d]].rnd > node[r].rnd) {
                    rotate(d^1, r);
                } else {
                    maintain(r);
                }
            }
        } else {
            r = newnode(data);
        }
    }
    void getkth(int k, int r, TYPE& data) {
        int x = node[r].son[0] ? node[node[r].son[0]].siz : 0;
        int y = node[r].dup;
        if (k <= x) {
            getkth(k, node[r].son[0], data);
        } else if (k <= x + y) {
            data = node[r].data;
        } else {
            getkth(k-x-y, node[r].son[1], data);
        }
    }
    TYPE getksum(int k, int r) {
        if (k <= 0 || r == 0) return 0;
        int x = node[r].son[0] ? node[node[r].son[0]].siz : 0;
        int y = node[r].dup;
        if (k <= x) return getksum(k, node[r].son[0]);
        if (k <= x+y) return node[node[r].son[0]].sum + node[r].data * (k-x);
        return node[node[r].son[0]].sum + node[r].data * y + getksum(k-x-y,node[r].son[1]);
    }
    void erase(const TYPE& data, int & r) {
        if (r == 0) return;
        int d = -1;
        if (data < node[r].data) {
            d = 0;
        } else if (node[r].data < data) {
            d = 1;
        }
        if (d == -1) {
            node[r].dup -= 1;
            if (node[r].dup > 0) {
                maintain(r);
            } else {
                if (node[r].son[0] == 0) {
                    r = node[r].son[1];
                } else if (node[r].son[1] == 0) {
                    r = node[r].son[0];
                } else {
                    int dd = node[node[r].son[0]].rnd > node[node[r].son[1]].rnd ? 1 : 0;
                    rotate(dd, r);
                    erase(data, node[r].son[dd]);
                }
            }
        } else {
            erase(data, node[r].son[d]);
        }
        if (r) maintain(r);
    }
    int ltcnt(const TYPE& data, int r) {
        if (r == 0) return 0;
        int x = node[r].son[0] ? node[node[r].son[0]].siz : 0;
        if (data < node[r].data) {
            return ltcnt(data, node[r].son[0]);
        }
        if (!(data < node[r].data) && !(node[r].data < data)) {
            return x;
        }
        return x + node[r].dup + ltcnt(data, node[r].son[1]);
    }
    int gtcnt(const TYPE& data, int r) {
        if (r == 0) return 0;
        int x = node[r].son[1] ? node[node[r].son[1]].siz : 0;
        if (data > node[r].data) {
            return gtcnt(data, node[r].son[1]);
        }
        if (!(data < node[r].data) && !(node[r].data < data)) {
            return x;
        }
        return x + node[r].dup + gtcnt(data, node[r].son[0]);
    }
    int count(const TYPE& data, int r) {
        if (r == 0) return 0;
        if (data < node[r].data) return count(data, node[r].son[0]);
        if (node[r].data < data) return count(data, node[r].son[1]);
        return node[r].dup;
    }
    void prev(const TYPE& data, int r, TYPE& result, bool& ret) {
        if (r) {
            if (node[r].data < data) {
                if (ret) {
                    result = max(result, node[r].data);
                } else {
                    result = node[r].data;
                    ret = true;
                }
                prev(data, node[r].son[1], result, ret);
            } else {
                prev(data, node[r].son[0], result, ret);
            }
        }
    }
    void next(const TYPE& data, int r, TYPE& result, bool& ret) {
        if (r) {
            if (data < node[r].data) {
                if (ret) {
                    result = min(result, node[r].data);
                } else {
                    result = node[r].data;
                    ret = true;
                }
                next(data, node[r].son[0], result, ret);
            } else {
                next(data, node[r].son[1], result, ret);
            }
        }
    }
    vector<Node> node;
    int root, total;
    bool multiple;
    bool insert(const TYPE& data) {
        bool ret = true;
        insert(data, root, ret);
        return ret;
    }
    bool kth(int k, TYPE &data) {
        if (!root || k <= 0 || k > node[root].siz)
            return false;
        getkth(k, root, data);
        return true;
    }
    TYPE ksum(int k) {
        assert(root && k>0 && k<=node[root].siz);
        return getksum(k, root);
    }
    int count(const TYPE &data) {
        return count(data, root);
    }
    int size() const {
        return root ? node[root].siz : 0;
    }
    void erase(const TYPE& data) {
        return erase(data, root);
    }
    int ltcnt(const TYPE& data) {
        return ltcnt(data, root);
    }
    int gtcnt(const TYPE& data) {
        return gtcnt(data, root);
    }
    int lecnt(const TYPE& data) {
        return size() - gtcnt(data, root);
    }
    int gecnt(const TYPE& data) {
        return size() - ltcnt(data, root);
    }
    bool prev(const TYPE& data, TYPE& result) {
        bool ret = false;
        prev(data, root, result, ret);
        return ret;
    }
    bool next(const TYPE& data, TYPE& result) {
        bool ret = false;
        next(data, root, result, ret);
        return ret;
    }
};

struct node {
    int idx, x, y, ans;
};
class Solution {
public:
    vector<int> countRectangles(vector<vector<int>>& rect, vector<vector<int>>& points) {
        int n = rect.size();
        int m = points.size();
        sort(rect.begin(), rect.end(), [&](auto &x, auto &y){return x[1]>y[1];});
        vector<node> vn(m);
        for (int i = 0; i < m; i++) {
            vn[i] = {i, points[i][0], points[i][1], 0};
        }
        sort(vn.begin(), vn.end(), [&](auto &a, auto &b){return a.y>b.y;});
        vector<int> ans(m);
        Treap<long long> tp(50005, true);
        for (int i = 0, j = 0; i < m; i++) {
            while (j < n && rect[j][1] >= vn[i].y) {
                tp.insert(rect[j][0]);
                j += 1;
            }
            ans[vn[i].idx] = tp.gecnt(vn[i].x);
        }
        return ans;
    }
};

标签:node,return,int,数目,son,lc2250,TYPE,矩形,data
From: https://www.cnblogs.com/chenfy27/p/18076963

相关文章

  • lc493 统计重要翻转对的数目
    给定一个数组nums[n],如果i<j并且nums[i]>2*nums[j],则称(i,j)是一个重要翻转对。求nums[n]中重要翻转对的数量。1<=n<=5e4;nums[i]在int范围内直接套平衡树模板即可。template<typenameTYPE>structTreap{structNode{TYPEdata,sum;intrnd,siz......
  • HDU 2056:Rectangles(两个矩形交点的性质)
    一、原题链接Problem-2056(hdu.edu.cn)二、题面Giventworectanglesandthecoordinatesoftwopointsonthediagonalsofeachrectangle,youhavetocalculatetheareaoftheintersectedpartoftworectangles.itssidesareparalleltoOXandOY.三、......
  • WPF绘图指南:用XAML轻松实现圆、线、矩形、文字、图片创意元素
     概述:在WPF中,通过使用不同的元素如Ellipse、Line、Rectangle等,可以轻松绘制各种图形,包括圆、线条、椭圆、矩形、多边形等。同时,通过TextBlock展示文字,Image展示图片,以及Path创建路径和曲线,使得图形的绘制变得灵活多样。通过简单的XAML代码,开发者可以快速构建各种图形和界面元......
  • [NOIP2017 提高组] 小凯的疑惑 / [蓝桥杯 2013 省] 买不到的数目
    这肯定是学证明了,看这篇文章补充一下细节首先,\(m\)的范围应该是\([0,b-1]\)然后,当\(m\)取不同值的时候,\(ma\)%\(b\)一定为不同值(这个性质确实有点奇特,可以记下来)反证,如果\(m_1a\equivm_2a\:(mod\:b)\)且\(0≤m_1<m_2≤b-1\),那么就有\(b|(m_2-m_1)a\),题目给出了\(a,b\)互质,......
  • 矩形总面积
    试题D:矩形总面积【问题描述】平面上有个两个矩形R1和R2,它们各边都与坐标轴平行。设(x1,y1)和(x2,y2)依次是R1的左下角和右上角坐标,(x3,y3)和(x4,y4)依次是R2的左下角和右上角坐标,请你计算R1和R2的总面积是多少?注意:如果R1和R......
  • 代码随想录 day64 柱状图中最大的矩形
    柱状图中最大的矩形本题和接雨水在很多地方都很相似但是不是求凹槽了而是求突起就是相同的思路求不同的柱体对于每一个柱体找左边最矮的柱体这个柱体的右边的柱体和这个柱体围成的矩形就为最大同理找右边的柱体这里注意要用while而不是if因为要找到最矮的而......
  • 【Filament】绘制矩形
    1前言​Filament环境搭建中介绍了Filament的Windows和Android环境搭建,绘制三角形中介绍了绘制纯色和彩色三角形,本文将使用Filament绘制纯色和彩色矩形。2绘制矩形​本文项目结构如下,完整代码资源→Filament绘制矩形。2.1自定义基类​为方便读者将......
  • 已知椭圆长轴,短轴,圆心,旋转角度求任意椭圆外包矩形
    参考:https://blog.csdn.net/fangmin723/article/details/118595271参考:https://blog.csdn.net/liuxiang3/article/details/114258907一、已知椭圆长轴,短轴,圆心,旋转角度求椭圆(旋转未做平移)方程一般式:一般来说,椭圆可以以任何一点为中心,也可以有与坐标轴不平行的轴。这样的椭圆总......
  • 蓝桥杯2022年第十三届省赛真题-矩形拼接
    目录题目分析代码题目分析情况1:三个矩形有一边相等。(完全匹配:4边)情况2:三个矩形中有前两个矩形的边等于第三个矩形的边,而且前两个矩形的另一条边相等。(完全匹配:4边)情况3:三个矩形中有前两个矩形的边等于第三个矩形的边,而且前两个矩形的另一条边不相等。(部分匹配:6边)......
  • 【libGDX】使用Mesh绘制矩形
    1前言​使用Mesh绘制三角形中介绍了绘制三角形的方法,本文将介绍绘制正方形的方法。​libGDX以点、线段、三角形为图元,没有提供绘制矩形内部的接口。要绘制矩形内部,必须通过三角形拼接而成,如下图,是通过GL_TRIANGLE_FAN模式绘制矩形。​绘制的坐标点如下,屏幕中......