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;
}
/**
**/


目录
相关文章
|
6月前
|
缓存 监控 Java
游戏服务器开服异常Check List
游戏服务器开服异常Check List
26 0
|
存储 Java 缓存
|
编解码 Java 数据库
|
Web App开发 测试技术 UED
Web交互设计优化的简易check list
Web交互设计优化的简易check list 00 | 时间: 2011-02-11 | 28,842 Views 交互设计, 用户研究   “优化已有产品的体验”,这是用户体验相关岗位职责中常见的描述。
1097 0
|
C#
Csharp: Treeview check list value
/// &lt;summary&gt; /// 選擇的節點 /// 塗聚文 20121116 /// 捷為工作室 /// /// &lt;/summary&gt; /// &lt;param name="sender"&gt;&lt;/param&gt;
1275 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.
814 0
|
3天前
|
存储 安全 算法
Java一分钟之-Java集合框架入门:List接口与ArrayList
【5月更文挑战第10天】本文介绍了Java集合框架中的`List`接口和`ArrayList`实现类。`List`是有序集合,支持元素重复并能按索引访问。核心方法包括添加、删除、获取和设置元素。`ArrayList`基于动态数组,提供高效随机访问和自动扩容,但非线程安全。文章讨论了三个常见问题:索引越界、遍历时修改集合和并发修改,并给出避免策略。通过示例代码展示了基本操作和安全遍历删除。理解并正确使用`List`和`ArrayList`能提升程序效率和稳定性。
10 0
|
3天前
|
存储 安全 Java
【JAVA基础篇教学】第八篇:Java中List详解说明
【JAVA基础篇教学】第八篇:Java中List详解说明
|
3天前
|
存储 安全 Java
Java容器类List、ArrayList、Vector及map、HashTable、HashMap
Java容器类List、ArrayList、Vector及map、HashTable、HashMap