7GOJ 计划 [CDQ分治]

本文介绍了一种使用CDQ分治算法解决二维偏序问题的方法,并通过坐标离散化技术来优化处理过程。该算法适用于解决点集中的部分排序问题,通过递归分解问题规模并利用二分查找减少重复计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:裸的二维偏序
直接上CDQ乱搞,或者线段树。。。。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mid ((l+r)>>1)
const int N=200010;
using namespace std;//CDQ分治+坐标离散化 
int a[N],b[N],x[N],y[N],id[N],n;
long long ans;
inline bool cmpf(const int &i,const int &j){//排序x 
    return x[i]<x[j];
}
inline bool cmps(const int &i,const int &j){//排序y 
    return y[i]<y[j];
}
inline void cdq(int l,int r,int tx=0,int ty=0){//直接上cdq分治。log_n^2 
    if(l==r)return;
    cdq(l,mid),cdq(mid+1,r);
    sort(id+l,id+mid+1,cmps);//
    sort(id+mid+1,id+r+1,cmps);//
    for(register int i=mid+1,j=l;i<=r;i++){
        while(j<=mid&&y[id[j]]<y[id[i]]){//以x排序过,只需要判定y 
            while(tx>0&&x[a[tx-1]]<x[id[j]])tx--;
            a[tx++]=id[j++];
        }
        while(ty>0&&x[b[ty-1]]>x[id[i]])ty--;
        if(ty>0)ans-=lower_bound(a,a+tx,b[ty-1],cmps)-a;//二分查找,求得重复计算的值。 
        ans+=tx;
        b[ty++]=id[i];
    }
}
inline void read(int &res){
    static char ch;int flag=1;
    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
int main(){
    freopen("project.in","r",stdin);
    freopen("project.out","w",stdout);
    read(n);
    for(register int i=1;i<=n;++i)read(x[i]),read(y[i]),id[i]=i;
    sort(id+1,id+n+1,cmpf);//总体查找顺序按照x大小排序。 
    cdq(1,n);
    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值