\(CDQ\) 分治的神奇操作

这个问题跟偏序问题好像差的不小啊

但是就是可以转化过去

对于一个查询我们可以把它拆成四个,也就是用二维前缀和的方式来查询

我们发现其实前缀和的定义就是多少个点的横纵坐标都小于这个点

典型的偏序问题

于是直接上\(cdq\)了

代码


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define re register
#define maxn 500005
#define LL long long
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define lowbit(x) ((x)&(-x))
inline int read()
{
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
struct Node
{
int x,y,ans,o,rk;
}b[maxn*5],a[maxn*5];
int c[2][maxn*10];
int n,m,tot,num;
int sz[2],Ans[maxn];
int bit[maxn*10];
inline int ask(int x){int now=0;for(re int i=x;i;i-=lowbit(i)) now+=bit[i];return now;}
inline void add(int x,int val){for(re int i=x;i<=sz[1];i+=lowbit(i)) bit[i]+=val;}
inline int find(int x,int o)
{
int l=1,r=sz[o];
while(l<=r)
{
int mid=l+r>>1;
if(c[o][mid]==x) return mid;
if(c[o][mid]>x) r=mid-1;
else l=mid+1;
}
return 0;
}
inline int cmp(Node A,Node B)
{
if(A.x==B.x) return A.y<B.y;
return A.x<B.x;
}
void CDQ(int s,int t)
{
if(s==t) return;
int mid=s+t>>1;
CDQ(s,mid),CDQ(mid+1,t);
int i=s,j=mid+1,p=i;
while(i<=mid&&j<=t)
{
if(b[i].x<=b[j].x)
{
if(!b[i].o) add(b[i].y,1);
a[p++]=b[i++];
}
else
{
if(b[j].o) b[j].ans+=ask(b[j].y);
a[p++]=b[j++];
}
}
while(j<=t)
{
if(b[j].o) b[j].ans+=ask(b[j].y);
a[p++]=b[j++];
}
for(re int k=s;k<i;k++) if(!b[k].o) add(b[k].y,-1);
while(i<=mid) a[p++]=b[i++];
for(re int k=s;k<=t;k++) b[k]=a[k];
}
int main()
{
n=read(),m=read();
tot=0;
for(re int i=1;i<=n;i++)
b[i].x=read(),b[i].y=read(),c[0][++tot]=b[i].x,c[1][tot]=b[i].y;
num=n;
int xx,yy,X,Y;
for(re int i=1;i<=m;i++)
{
xx=read(),yy=read(),X=read(),Y=read(); b[++num].x=X,b[num].y=Y,b[num].o=1,b[num].rk=i;
c[0][++tot]=b[num].x,c[1][tot]=b[num].y; b[++num].x=xx-1,b[num].y=yy-1,b[num].o=1,b[num].rk=i;
c[0][++tot]=b[num].x,c[1][tot]=b[num].y; b[++num].x=X,b[num].y=yy-1,b[num].o=2,b[num].rk=i;
c[0][++tot]=b[num].x,c[1][tot]=b[num].y; b[++num].x=xx-1,b[num].y=Y,b[num].o=2,b[num].rk=i;
c[0][++tot]=b[num].x,c[1][tot]=b[num].y;
}
std::sort(c[0]+1,c[0]+tot+1);
std::sort(c[1]+1,c[1]+tot+1);
sz[0]=std::unique(c[0]+1,c[0]+tot+1)-c[0]-1;
sz[1]=std::unique(c[1]+1,c[1]+tot+1)-c[1]-1;
for(re int i=1;i<=num;i++)
b[i].x=find(b[i].x,0),b[i].y=find(b[i].y,1);
CDQ(1,num);
for(re int i=1;i<=num;i++)
{
if(!b[i].o) continue;
if(b[i].o==1) Ans[b[i].rk]+=b[i].ans;
else Ans[b[i].rk]-=b[i].ans;
}
for(re int i=1;i<=m;i++)
printf("%d\n",Ans[i]);
return 0;
}

【[SHOI2007]园丁的烦恼】的更多相关文章

  1. P2163 [SHOI2007]园丁的烦恼

    题目 P2163 [SHOI2007]园丁的烦恼 做法 关于拆点,要真想拆直接全部用树状数组水过不就好了 做这题我们练一下\(cdq\)分治 左下角\((x1,y1)\)右上角\((x2,y2)\), ...

  2. bzoj1935 [Shoi2007]园丁的烦恼

    bzoj1935 [Shoi2007]园丁的烦恼 有N个点坐标为(xi,yi),M次询问,询问(a,b)-(c,d)的矩形内有多少点. 0≤n≤500000,1≤m≤500000,0≤xi,yi≤10 ...

  3. 洛谷 P2163 [SHOI2007]园丁的烦恼 (离线sort,树状数组,解决三维偏序问题)

    P2163 [SHOI2007]园丁的烦恼 题目描述 很久很久以前,在遥远的大陆上有一个美丽的国家.统治着这个美丽国家的国王是一个园艺爱好者,在他的皇家花园里种植着各种奇花异草. 有一天国王漫步在花园 ...

  4. [LuoguP2163][SHOI2007]园丁的烦恼_CDQ分治

    园丁的烦恼 题目链接:https://www.luogu.org/problem/P2163 数据范围:略. 题解: 树套树过不去,那就$CDQ$分治好了. 有点小细节,但都是$CDQ$分治必要的. ...

  5. P2163 【[SHOI2007]园丁的烦恼】

    其实是不用把一个询问拆成四个的 把询问转化为数学语言: 对于每个查询,询问满足$a<=x<=b$且$c<=y<=d$的点$x,y$的个数 ~~自然~~想到偏序问题,看到有两个式 ...

  6. P2163 [SHOI2007]园丁的烦恼(cdq分治)

    思路 其实是cdq的板子 题目要求询问对于每个给出的xi,yi,xj,yj形如xi<=x<=xj.yi<=y<=yj的x,y对数有多少组 改成四个询问,拆成四个前缀和的形式后就 ...

  7. BZOJ1935或洛谷2163 [SHOI2007]园丁的烦恼

    BZOJ原题链接 洛谷原题链接 很容易想到二维前缀和. 设\(S[i][j]\)表示矩阵\((0, 0)(i, j)\)内树木的棵数,则询问的矩形为\((x, y)(xx, yy)\)时,答案为\(S ...

  8. [SHOI2007]园丁的烦恼

    裸的二维数点 #include"cstdio" #include"cstring" #include"iostream" #include& ...

  9. luoguP2163 [SHOI2007]园丁的烦恼

    安利系列博文 https://www.cnblogs.com/tyner/p/11565348.html https://www.cnblogs.com/tyner/p/11605073.html 题 ...

随机推荐

  1. 《Centos服务器版安装教程》

    安装前准备: (1)  首先大家需要在电脑上安装一个VMware (2)  Centos7系列的一个服务器版镜像 有了这两样东西,下面我们就开始安装了 一.     打开VMware,新建一个虚拟机 ...

  2. Fork开源项目之通讯框架

    项目发布于:https://github.com/HouZhiHouJue/IOCPMSG.看代码前请先看简介.

  3. java 基础 --- 动态代理和静态代理

    问题  : 代理的应用场景是什么 动态代理的底层原理是什么,为什么只能继承接口 概述 代理模式是设计模式的一种,简单地说就是调用代理类的方法实际就是调用真实类的方法.这种模式在AOP (切面编程)中非 ...

  4. PHP高级工程师面试 - 笔试题

    Part1:HTTP协议 1.状态码的含义 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明 100 (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求 ...

  5. 最短路问题(dijkstral 算法)(优化待续)

    迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向 ...

  6. Oracle数据库基本操作(一) —— Oracle数据库体系结构介绍、DDL、DCL、DML

    一.Oracle数据库介绍 1.基本介绍 Oracle数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/ ...

  7. oracle数据库的安装与连接关键点

    一.window xp系统上安装Oracle Database 10G 解锁Scott.Hr账号并重置口令 远程连接数oracle数据库地址 二.在Mac系统上使用Navicat远程连接oracle数 ...

  8. qt5.6.3下使用firebird

    有人把firebird比作数据库界的瑞士军刀,想学习一下其在QT5.6中的使用,于是便开始了一场自己挖坑,自己埋的旅程. 环境说明:win7 64位+QT5.6 mingw4.9 32位(好像官网上也 ...

  9. drupal 开发笔记

    “以前我在开发Java项目的时候,都需要自己设计数据库表结构,数据库表结构的设计关系到一个人开发技能的高低,而在Drupal里面,我们通常是不需要设计数据库表结构,我们要做的是创建新的内容类型,然后为 ...

  10. Setting up a Single Node Cluster Hadoop on Ubuntu/Debian

    Hadoop: Setting up a Single Node Cluster. Hadoop: Setting up a Single Node Cluster. Purpose Prerequi ...