BZOJ 1790: [Ahoi2008]Rectangle 矩形藏宝地
BZOJ 1790: [Ahoi2008]Rectangle 矩形藏宝地
题目传送门
【题目大意】
游戏的主办方把这块开阔地当作第一象限,将所有可能埋藏宝藏的地方划成一个个矩形的土地,并把这些矩形土地的坐标都告诉了参赛者。挖宝的提示很简单,只要某一个矩阵土地至少被另外一个矩阵土地所包含,那么这个矩阵土地里肯定埋有宝藏。问:有多少个矩形土地里肯定埋有宝藏?
其实就是求对于矩形i,是否存在一个矩形j,使得aj<ai,bj<bi,cj>ci,dj>di。
并不要求在线,用离线算法就好了。(CDQ分治)
先对a排序,取mid,表示i小于等于mid的标记为添加,大于mid的标记为查询。
再对b排序,保证b是从小到大的,遇到添加的就将c作为下标,存d(线段树维护最大值),查询的就询问c+1~n的最大值是否大于d,是,标记当前矩形为藏宝地,不能直接ans++,会计算重复。
为什么这是对的?
因为查询的a一定比添加的a大,又对b进行排序,又保证了b有序。那么查询的矩阵A找到的添加的矩阵B,一定是B.a<A.a,B.b<A.b,剩下的就不解释了……
这题卡常,排序一定要写好。(TLE了好多次……)
#include<cstdio>
#include<algorithm>
#define imax(a,b) ((a>b)?(a):(b))
using namespace std;
const int N=200010;
int A[N],B[N],C[N],D[N],*Ry,id[N];
struct data{ int id; bool p; } np[N];
int n,px,T[N<<2],ans;
bool vis[N];
void updata(int ro,int L,int R,int x,int val)
{
if(x<L || x>R) return;
if(L==x && R==x)
{
T[ro]=val;
return;
}
int Mid=(L+R)>>1;
updata(ro<<1,L,Mid,x,val); updata(ro<<1|1,Mid+1,R,x,val);
T[ro]=imax(T[ro<<1],T[ro<<1|1]);
}
int query(int ro,int L,int R,int li,int ri)
{
if(L>ri || R<li) return 0;
if(li<=L && R<=ri) return T[ro];
int Mid=(L+R)>>1;
int q1=query(ro<<1,L,Mid,li,ri),q2=query(ro<<1|1,Mid+1,R,li,ri);
return imax(q1,q2);
}
bool cmp(int a,int b) { return (Ry[a]<Ry[b]); }
bool Cmp(data A,data B) { return (Ry[A.id]<Ry[B.id]); }
void CDQ(int L,int R)
{
if(L==R) return;
int Mid=(L+R)>>1;
for(int i=L;i<=Mid;i++) np[i].p=1;
Ry=B; sort(np+L,np+R+1,Cmp);
for(int i=L;i<=R;i++)
{
if(np[i].p) updata(1,1,n,C[np[i].id],D[np[i].id]); else
if(query(1,1,n,C[np[i].id]+1,n)>D[np[i].id]) vis[np[i].id]=1;
}
for(int i=L;i<=R;i++) if(np[i].p) updata(1,1,n,C[np[i].id],0),np[i].p=0;
Ry=A; sort(np+L,np+R+1,Cmp);
CDQ(L,Mid); CDQ(Mid+1,R);
}
int read()
{
int yu=0;
char ch=getchar();
while(ch>'9' || ch<'0') ch=getchar();
while(ch>='0' && ch<='9')
{
yu=(yu<<3)+(yu<<1)+ch-'0';
ch=getchar();
}
return yu;
}
void work()
{
for(int i=1;i<=n;i++) id[i]=i;
sort(id+1,id+1+n,cmp);
for(int i=1;i<=n;i++) Ry[id[i]]=i;
}
int main()
{
scanf("%d",&n); ans=0;
for(int i=1;i<=n;i++)
{
A[i]=read(); B[i]=read();
C[i]=read(); D[i]=read();
}
Ry=D; work(); Ry=C; work();
Ry=B; work(); Ry=A; work();
for(int i=1;i<=n;i++) np[i].id=id[i];
CDQ(1,n); for(int i=1;i<=n;i++) if(vis[i]) ans++;
printf("%d\n",ans);
return 0;
}
BZOJ 1790: [Ahoi2008]Rectangle 矩形藏宝地的更多相关文章
- [BZOJ1790][AHOI2008]Rectangle 矩形藏宝地(四维偏序,CDQ+线段树)
1790: [Ahoi2008]Rectangle 矩形藏宝地 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 553 Solved: 193[Subm ...
- bzoj1790: [Ahoi2008]Rectangle 矩形藏宝地
被统考草翻回来做题不太行啊,线段树和cdq都写挂细节 这题大概就是四维偏序吧,欸n怎么到了20w,只能水70啊 但是这个好像只要有1个在里面就可以ans就可以++了耶 突然想到高中奥数老师说的,大概是 ...
- 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)
题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...
- ●BZOJ 1185 [HNOI2007]最小矩形覆盖
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1185 题解: 计算几何,凸包,旋转卡壳 结论:矩形的某一条边在凸包的一条边所在的直线上. ( ...
- BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子
来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...
- bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳
题目大意 用最小矩形覆盖平面上所有的点 分析 有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小 简略证明 我们逆时针枚举一条边 用旋转卡壳维护此时最左,最右,最上的点 注意 注 ...
- bzoj 1787 [Ahoi2008]Meet 紧急集合(1832 [AHOI2008]聚会)
1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1841 Solved: 857[Submit][ ...
- BZOJ 1832: [AHOI2008]聚会( LCA )
LCA模板题...不难发现一定是在某2个人的LCA处集合是最优的, 然后就3个LCA取个最小值就OK了. 距离就用深度去减一减就可以了. 时间复杂度O(N+MlogN) (树链剖分) -------- ...
- BZOJ 1787: [Ahoi2008]Meet 紧急集合( 树链剖分 )
这道题用 LCA 就可以水过去 , 但是我太弱了 QAQ 倍增写LCA总是写残...于是就写了树链剖分... 其实也不难写 , 线段树也不用用到 , 自己YY一下然后搞一搞就过了...速度还挺快的好像 ...
随机推荐
- 【转】Java的可变类与不可变类
1.可变类和不可变类(Mutable and Immutable Objects)的初步定义: 可变类:当你获得这个类的一个实例引用时,你可以改变这个实例的内容. 不可变类:当你获得这个类的一个实例引 ...
- C - Valera and Fruits
Problem description Valera loves his garden, where n fruit trees grow. This year he will enjoy a gre ...
- C# 常用代码片段
一.从控制台读取东西代码片断: using System; class TestReadConsole { public static void Main() { Console.Write(Ente ...
- resgen.exe 已退出 代码为 1073741701的错误的解决办法
以管理员的身份打开命令提示窗口:(开始-运行-cmd),更改目录至"CD C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\”下 ...
- listview 控件
private void Form1_Load(object sender, EventArgs e) { //设置该listview关联的imagelist listView1.LargeImage ...
- 实现model中的文件上传FTP(一)
由于在django的model中配置了filefield或者imagefield配置了upload_to参数只能将用户上传的文件上传到项目本地,就算重定向到项目外也只是直接读取文件系统,这样对未来的项 ...
- js中获取浏览器和屏幕高度
Javascript: IE中: document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ==> BODY对象高 ...
- C# 分割URL地址
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_C ...
- Spring cloud父项目的建立
1.建立一个maven项目 注意建立项目的时候.选择pom的包 2.添加架包 <project xmlns="http://maven.apache.org/POM/4.0.0&quo ...
- nyoj27-水池数目【DFS】
题目描述: 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在,你的任务来了,请用计算机算出该地图中共有几个水 ...