首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

二维偏序问题

编程知识
2024年08月17日 22:32

偏序关系

大概就是,满足自反性,反对称性,传递性。
将严格偏序关系建图,可以得到一个DAG(有向无环图)

二维偏序问题是:给定 \(n\) 个元素,每个元素有\(2\)个属性,定义某种偏序关系,对于所有 \(x_i\) ,求 \(x_j \prec x_i\) 的数量。

一种基本的操作方法是,某个属性按大小排序,另一个属性利用树状数组/线段树进行数量,求和等操作。这种处理方式要依靠在询问可以离线的前提下。

这里有个经典例题,二维数点问题。

P2163 [SHOI2007] 园丁的烦恼

大概题意:

第一行有两个整数 \(n, m\),分别表示点个数和询问次数。
接下来 \(n\) 行,每行两个整数 \(x, y\),表示存在坐标为 \((x, y)\) 的点。有可能存在点位于同一坐标。
接下来 \(m\) 行,每行四个整数 \(a, b, c, d\),表示查询以 \((a, b)\) 为左下角,\((c, d)\) 为右上角的矩形内部(包括边界)有多少个点。
\(0 \le n \le 5 \times 10^5\)\(1 \le m \le 5 \times 10^5\)\(0 \le x, y, a, b, c, d \le 10^7\)\(a \le c\)\(b \le d\)

初步的想法:对于 \(n\)\(m\) 较小的情况,可以用二维前缀和。

可以巧妙的用每个点 \(x\) 值的处理顺序,分隔开询问矩形的 \(x\) 区间的影响。对于 \(y\) 值,用树状数组查询需要的范围。

可以想到以下做法:

对所有的询问离线。将每个矩形拆分成 \((a-1,b-1)(a-1,d)(c,b-1)(c,d)\) 四个点,像前缀和一样算贡献。
依次处理每一个点,将询问点中 \(x’\) 之前的点的 \(y\) 值全部加入树状数组中,在查询 \(y'\) 计算贡献。

Code:

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
inline int read(){
    int f=1,x=0;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return f*x;
}
int n,m;
int cnt1;
struct node{
    int x,y;
    int id,ff;
    bool operator<(const node& p)const{
        if(x==p.x)return y<p.y;
        else return x<p.x;
    }
}a[N],b[N*4];
int ans[N];
int mp[N*3],len;
int c[N*3];
inline int lowbit(int x){
    return x&-x;
}
inline void upd(int x,int w){
    for(int i=x;i<=len;i+=lowbit(i)){
        c[i]+=w;
    }
}
inline int qur(int x){
    int res=0;
    for(int i=x;i;i-=lowbit(i)){
        res+=c[i];
    }
    return res;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++){
        a[i].x=read(),a[i].y=read();
        mp[++len]=a[i].y;
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=m;i++){
        int xa=read(),ya=read(),xb=read(),yb=read();
        b[++cnt1]={xa-1,ya-1,i,1};
        b[++cnt1]={xa-1,yb,i,-1};
        b[++cnt1]={xb,ya-1,i,-1};
        b[++cnt1]={xb,yb,i,1};
        mp[++len]=ya-1,mp[++len]=yb;
    }
    sort(b+1,b+1+cnt1);
    sort(mp+1,mp+1+len);
    len=unique(mp+1,mp+1+len)-mp-1;
    for(int i=1;i<=n;i++){
        a[i].y=lower_bound(mp+1,mp+1+len,a[i].y)-mp;
    }
    for(int i=1;i<=cnt1;i++){
        b[i].y=lower_bound(mp+1,mp+1+len,b[i].y)-mp;
    }
    int now=0;
    for(int i=1;i<=cnt1;i++){
        int x=b[i].x,y=b[i].y;
        int id=b[i].id,ff=b[i].ff;
        while(now+1<=n&&a[now+1].x<=x){
            now++;
            upd(a[now].y,1);
        }
        ans[id]+=qur(y)*ff;
    }
    for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
    return 0;
}

当然,更多的并不是这样明显的二维偏序关系,常常需要观察得出偏序关系是什么,应该怎么处理。

例题1:P8844 [传智杯 #4 初赛] 小卡与落叶

我写的:做法

From:https://www.cnblogs.com/TanHaoren/p/18362076
本文地址: http://shuzixingkong.net/article/1194
0评论
提交 加载更多评论
其他文章 痞子衡嵌入式:英飞凌MirrorBit工艺NOR Flash的扇区架构设计
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家讲的是英飞凌MirrorBit工艺NOR Flash的扇区架构设计。 NOR Flash 大家都很熟悉,其内部按组织从小到大分为 Page(128B/256B/512B)、Sector(4KB)、Block(32KB/64KB/128KB/25
痞子衡嵌入式:英飞凌MirrorBit工艺NOR Flash的扇区架构设计 痞子衡嵌入式:英飞凌MirrorBit工艺NOR Flash的扇区架构设计 痞子衡嵌入式:英飞凌MirrorBit工艺NOR Flash的扇区架构设计
Github Dorisoy网盘项目
相关github地址 https://github.com/dorisoy/Dorisoy.Pan?tab=readme-ov-file mysql8 sudo rpm -ivh mysql80-community-release-el7-5.noarch.rpm wget https://dev.
Github Dorisoy网盘项目 Github Dorisoy网盘项目 Github Dorisoy网盘项目
cloud compare PCA插件开发详细步骤(二)附代码
在上一节 https://blog.csdn.net/csy1021/article/details/141200135 我们已经完成了 具体开发前的准备工作,包括 各级 CMakelists.txt 的设置,相关内容的修改,并已成功编译 如需整个插件项目,编译后的 dll,或其他帮助,欢迎留言、私
cloud compare PCA插件开发详细步骤(二)附代码 cloud compare PCA插件开发详细步骤(二)附代码 cloud compare PCA插件开发详细步骤(二)附代码
python中怎样指定open编码为ansi
本文简要介绍了Python中open函数打开文件时,可以通过encoding参数来指定文件的编码方式,给出了详细的代码示例。
C#模拟键盘输入、键状态和监听键盘消息
模拟键盘输入 模拟键盘输入的功能需要依赖Windows函数实现,这个函数是SendInput,它是专门用来模拟键盘、鼠标等设备输入的函数。 另外和键盘输入相关的函数还有SendKeys,它是System.Windows.Forms. SendKeys,只能在WinFrom项目中使用,并且它的所有功能
C#实现国产Linux视频录制生成mp4(附源码,银河麒麟、统信UOS)
随着信创国产化浪潮的来临,在国产操作系统上的应用开发的需求越来越多。最近有个客户需要在银河麒麟和统信UOS上实现录制摄像头视频和麦克风声音,将它们录制成一个mp4文件。那么这样的功能要如何实现了?
C#实现国产Linux视频录制生成mp4(附源码,银河麒麟、统信UOS)
.NET中各种线程同步锁
编程编的久了,总会遇到多线程的情况,有些时候我们要几个线程合作完成某些功能,这时候可以定义一个全局对象,各个线程根据这个对象的状态来协同工作,这就是基本的线程同步。 ​支持多线程编程的语言一般都内置了一些类型和方法用于创建上述所说的全局对象也就是锁对象,它们的作用类似,使用场景有所不同。.Net中这
机器学习的数学基础--微积分
微积分运算在机器学习领域扮演着至关重要的角色,它不仅是许多基础算法和模型的核心,还深刻影响着模型的优化、性能评估以及新算法的开发。 掌握微积分,不仅让我们多会一种计算方式,也有助于理解各种机器学习算法和模型是如何寻找最优参数的。 1. 为什么需要微积分? 也许有些人会觉得微积分很难,这大概是因为我们
机器学习的数学基础--微积分 机器学习的数学基础--微积分 机器学习的数学基础--微积分