\(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. 删除Panl控件中窗体的方法

    //删除窗体方法 private void CloseFrm() { foreach (Control item in panel1.Controls) { if (item is Form) //判 ...

  2. 文本框改变之onpropertychange事件

    onpropertychange能够捕获每次输入值的变化. 例如:对象的value值被改变时,onpropertychange能够捕获每次改变,而onchange需要执行某个事件才可以捕获. 在文本框 ...

  3. memcache 学习笔记

    Memcached是国外社区网站LiveJournal的开发团队开发的高性能的分布式内存缓存服务器.一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度.提高可扩展 ...

  4. CodeForce 614B Gena's Code(水题)

    这道题提醒我两点: 1.break时一定要检查清楚 2.字符串直接赋值一定要注意结束符,最好能用strcpy 以上是debug的惨痛教训 #include <iostream> #incl ...

  5. 判断数组内是否有几个元素之和等于m

    #include<iostream> using namespace std; ]; int f(int n,int m) { ||m-a[n]==); &&m-a[n]! ...

  6. js 对象数组去重

    var arr = [{ "name": "ZYTX", "age": "Y13xG_4wQnOWK1QwJLgg11d0pS4h ...

  7. 利用Ogr将Kml转为Shape【1】

    最近在研究Kml怎么转化为Shape文件,因为客户中很多在原来采集了一部分数据都是在google Earth中,而我们的应用中特别需要这份数据,所以打算先在GE中把这份数据导出为Kml或Kmz文件,然 ...

  8. MUI框架-01-介绍-创建项目-简单页面

    MUI框架-01-介绍-准备-创建项目 从0开始快速高效学习 MUI 框架 官方文档:http://dev.dcloud.net.cn/mui/ui/ (1)MUI 介绍 MUI 是什么,解决了什么问 ...

  9. flask介绍

    安装flask pip3 install flask 短小精悍.可扩展强 的一个Web框架. 牛逼点:上下文管理机制 依赖wsgi: werkzeug(相当于Django的wsgi):只要安装flas ...

  10. mac安装软件提示没有权限

    Mac 安装软件基本是各种爽,自动更新啥. 但是有一种提示没有权限的错误,很不爽,还要sudo管理员权限 有一个修复 /usr/local目录权限的命令 sudo chown -R 'whoami' ...