Check List线段树维护偏序三元组

简介: 如上的问题是让求出满足三元组(xi,yi),(xj,yj)(xk,yk)且{xi < xj < xkyj < yi < yk}的数量这里的约束条件有两个,可以称作是二维偏序问题推荐一篇博客:链接这里面总结了一些经验关于这个题目,学长的博客链接里面讲到了一些做题的思路:按照x坐标进行排序,然后对y进行离散化处理(看数据范围就会发现y的数据范围达到了1e9,但是最多只会有2e5个点)之后,假设当前位置是pos

下面这个题是二维偏序问题

所谓偏序问题,是指多 约束 条件的元素统计等问题

如下:

题目链接


Check List


题目描述


When test driving a vehicle, you are asked to make a checkmark on a tablet. Upon inspection, you have noticed many fingerprints on the screen. Aside from the rush of disgust, you notice that the fingerprints on the screen can be represented by a series of 2D points on a standard Cartesian grid. You know that checkmarks can be uniquely defined by three points; these three points have distinct x coordinates and the three points also have distinct y coordinates. The leftmost point must be lower than the rightmost point and higher than the middle point. Now you want to know how many unique checkmarks you can make using the 2D points.


Let’s consider some examples. The three points (1,2), (2,1), and (3,2) do not form a valid checkmark because the leftmost and rightmost points are at the same height. The three points (1,2), (2,1), and (2,3) do not form a valid checkmark because two points have the same x coordinates. The three points (1,2), (3,1), and (4,9) do form a valid checkmark.


Given a list of 2D points, determine the number of unique checkmarks that can be formed from them.


输入描述:


The first input line contains a single integer, n (1 ≤ n ≤ 100,000), representing the number of points. Each of the following n input lines contains two integers, xi and yi (1 ≤ xi, yi ≤1,000,000,000), representing the location of a point on the 2D grid. No two points will be identical.


输出描述:


Print the number of distinct checkmarks that can be formed by the given 2D points.


示例1


输入

6 
6 6
5 3
1 5
3 2
4 4
2 1


输出

5


示例2


输入

10
4 2
9 4
1 5
2 4
10 5
6 1
3 3
8 3
5 1
7 2


输出

20


如上的问题是让求出满足三元组(xi,yi),(xj,yj)(xk,yk)

且{

xi < xj < xk

yj < yi < yk

}的数量

这里的约束条件有两个,可以称作是二维偏序问题


推荐一篇博客:链接

这里面总结了一些经验

关于这个题目,学长的博客 链接 里面讲到了一些做题的思路:

按照x坐标进行排序,然后对y进行离散化处理(看数据范围就会发现y的数据范围达到了1e9,但是最多只会有2e5个点)


之后,假设当前位置是pos

考虑当前位置作为第二个的贡献,即对所有之前出现过的数 大于h[pos]的+1

然后再加上pos作为第三个数的贡(即对答案的贡献)


所以你需要维护两个操作:

1.对所有出现过的数,在[x,y]区间内都+1

2.求所有出现过的数,在[x,y]区间内的权值


因为题目要求出现过,所以用 线段树 再次维护一个b权值,代表当前节点下,出现了多少个点

那么lazy 向下传 就不传 区间长度了 而是b[k]

每次单点修改时,将lazy传递下来,这样就不会影响新的lazy传递


/*** keep hungry and calm PushyTao!***/
#define PI (double)acos(-1.0)
#define md tree[rt].l+tree[rt].r>>1
typedef int itn;
vector<ll> vet;
struct node{
    int x,y;
    friend bool operator <(node a,node b){
        if(a.x != b.x) return a.x < b.x;
        else return a.y < b.y;
    }
}a[maxn];
struct SegmentTree{
    int l,r;
    ll sum1,sum2,lazy;
}tree[maxn<<2];
void PushUp(int rt){
    tree[rt].sum1 = tree[rt << 1].sum1 + tree[rt << 1 | 1].sum1;
    tree[rt].sum2 = tree[rt << 1].sum2 + tree[rt << 1 | 1].sum2;
}
void PushDown(int rt){
    if(tree[rt].lazy){
        tree[rt << 1].sum2 += tree[rt << 1].sum1 * tree[rt].lazy;
        tree[rt << 1 | 1].sum2 += tree[rt << 1 | 1].sum1 * tree[rt].lazy;
        tree[rt << 1].lazy += tree[rt].lazy;
        tree[rt << 1 | 1].lazy += tree[rt].lazy;
        tree[rt].lazy = 0;
    }
}
void Build(int rt,int l,int r){
    tree[rt].l = l;
    tree[rt].r = r;
    tree[rt].sum1 = tree[rt].sum2 = tree[rt].lazy = 0;
    if(l == r) return ;
    int mid = l + r >> 1;
    Build(rt << 1,l,mid);
    Build(rt << 1 | 1,mid + 1,r);
}
void UpdatePnt(int rt,int pos){
    if(tree[rt].l == tree[rt].r && tree[rt].r == pos){
        ++ tree[rt].sum1;
        return ;
    }
    PushDown(rt);
    ///int mid = md;
    if(pos <= md) UpdatePnt(rt << 1,pos);
    else UpdatePnt(rt << 1 | 1,pos);
    PushUp(rt);
}
void Update(int rt,int l,int r){
    if(tree[rt].r < l || tree[rt].l > r) return ;
    if(tree[rt].l >= l && tree[rt].r <= r){
        tree[rt].sum2 += tree[rt].sum1;
        ++ tree[rt].lazy;
        return ;
    }
    PushDown(rt);
    Update(rt << 1,l,r);
    Update(rt << 1 | 1,l,r);
}
ll Query(int rt,int l,int r){
    if(tree[rt].r < l || tree[rt].l > r) return 0LL;
    if(tree[rt].l >= l && tree[rt].r <= r){
        return tree[rt].sum2;
    }
    PushDown(rt);
    return Query(rt << 1,l,r) + Query(rt << 1 | 1,l,r);
}
int id(ll x){
    return lower_bound(vet.begin(),vet.end(),x) - vet.begin() + 1;
}
int main() {
    int n = read;
    for(int i=1;i<=n;i++){
        a[i].x = read,a[i].y = read;
        vet.push_back(a[i].y);
    }
    sort(a+1,a+1+n);
    sort(vet.begin(),vet.end());
    vet.erase(unique(vet.begin(),vet.end()),vet.end());
    int siz = vet.size();
    Build(1,1,siz);///total number of element is size
    ll ret = 0;
    for(int i=1;i<=n;i++){
        int p = i;
        while(p <= n && a[p].x == a[i].x){
            int _id = id(a[p].y);
            ret += Query(1,1,_id-1);
            ++ p;
        }
        p = i;
        while(p <= n && a[p].x == a[i].x){
            int _id = id(a[p].y);
            Update(1,_id+1,siz);
            ++ p;
        }
        p = i;
        while(p <= n && a[p].x == a[i].x){
            int _id = id(a[p].y);
            UpdatePnt(1,_id);
            ++ p;
        }
        i = p - 1;
    }
    cout << ret <<endl;
  return 0;
}
/**
**/


目录
相关文章
|
缓存 监控 Java
游戏服务器开服异常Check List
游戏服务器开服异常Check List
71 0
|
存储 Java 缓存
|
编解码 Java 数据库
|
Web App开发 测试技术 UED
Web交互设计优化的简易check list
Web交互设计优化的简易check list 00 | 时间: 2011-02-11 | 28,842 Views 交互设计, 用户研究   “优化已有产品的体验”,这是用户体验相关岗位职责中常见的描述。
1153 0
|
C#
Csharp: Treeview check list value
/// &lt;summary&gt; /// 選擇的節點 /// 塗聚文 20121116 /// 捷為工作室 /// /// &lt;/summary&gt; /// &lt;param name="sender"&gt;&lt;/param&gt;
1334 0
|
SQL 数据库 数据库管理
DBA Morning Check List
DBA Morning Check List By Bill Richards, 2010/08/27 (first published: 2008/04/14) Database Administrators can sometimes have one of the most stressful jobs in the company.
862 0
|
8月前
|
安全 Java
java线程之List集合并发安全问题及解决方案
java线程之List集合并发安全问题及解决方案
1120 1
|
7月前
|
Java API Apache
怎么在在 Java 中对List进行分区
本文介绍了如何将列表拆分为给定大小的子列表。尽管标准Java集合API未直接支持此功能,但Guava和Apache Commons Collections提供了相关API。
|
7月前
|
运维 关系型数据库 Java
PolarDB产品使用问题之使用List或Range分区表时,Java代码是否需要进行改动
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。