link

考虑简洁的 \(\text{cdq}\) 做法。

约定:第 \(i\) 个矩形左下角为 \((xl_i,yl_i)\),右上角为 \((xr_i,yr_i)\),所有坐标都已离散化。

如果 第 \(i\) 个矩形可以覆盖第 \(j\) 个矩形,那么必须满足:

  • \(i>j\)

  • \(xl_i\le xr_j,xr_i\ge xl_j\)(横向有交点)

  • \(yl_i\le yr_j,yr_i\ge yl_j\)(竖向有交点)

首先将矩形按照出现的顺序降序排列,解决完第一个条件。

考虑满足 \(xl_i\le xr_j\)。将 \([l,mid]\) 按照 \(xl\) 排序,\([mid+1,r]\) 按照 \(xr\) 排序,然后将满足 \(xl_i\le xr_j\) 条件的矩形存入线段树中(具体存法后文讲),这样在线段树中的矩形都随时满足 \(xl_i\le xr_j\)。

关键在于如何将矩形存储到线段树中来满足剩下三个条件。

将线段树看做纵坐标的值域,那么存储第 \(i\) 个矩形就一定是对区间 \([yl_i,yr_i]\) 进行操作,且操作的值一定和 \(xr_i\) 有关。

看到剩下的条件 \(xr_i\ge xl_j\),发现 \(xr_i\) 越大越好,于是存储矩形到线段树中的操作就很明了了,即 \([yl_i,yr_i]\) 更新最大值 \(xr_i\)。

设 \(f_j\) 表示第 \(j\) 个矩形是否被覆盖,线段树区间最大值为 \(g_{[l,r]}\),那么就有:

\[f_j=f_j|[g_{[yl_j,yr_j]}\ge xl_j]
\]

所以执行一遍 \(\text{cdq}\) 就全部搞定了。

关于线段树清空

在多设一个区间是否清空的懒标记,每次懒标记下传的时候,先下穿清空的懒标记,再下传正常的懒标记。

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=200010;
const int N=(maxn<<2);
inline int read(){
int x=0;
char c=getchar();
for(;!(c>='0'&&c<='9');c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return x;
}
struct node{
int id,xl,yl,xr,yr;
}a[maxn];
int data[N],lz[N],LZ[N];
//data为区间最值,lz为正常懒标记,LZ为清空懒标记
int X[N],Y[N];
int n,m;
bool f[maxn];
bool cmp1(node a,node b){
return a.xl<b.xl;
}
bool cmp2(node a,node b){
return a.xr<b.xr;
}
bool cmp3(node a,node b){
return a.id<b.id;
}
bool cmp4(node a,node b){
return a.id>b.id;
}
void pushdown(int i){
if(~LZ[i]){
//先下传清空懒标记(可以思考下传递顺序的问题)
lz[i<<1]=lz[i<<1|1]=0;
data[i<<1]=data[i<<1|1]=0;
LZ[i<<1]=LZ[i<<1|1]=0;
LZ[i]=-1;
}
lz[i<<1]=max(lz[i<<1],lz[i]);
lz[i<<1|1]=max(lz[i<<1|1],lz[i]);
data[i<<1]=max(data[i<<1],lz[i]);
data[i<<1|1]=max(data[i<<1|1],lz[i]);
lz[i]=0;
}
void add(int i,int l,int r,int L,int R,int x){
if(l>R||r<L) return ;
if(l>=L&&r<=R){
data[i]=max(data[i],x);
lz[i]=max(lz[i],x);
return ;
}
pushdown(i);
int mid=l+r>>1;
add(i<<1,l,mid,L,R,x);
add(i<<1|1,mid+1,r,L,R,x);
data[i]=max(data[i<<1],data[i<<1|1]);
}
int Query(int i,int l,int r,int L,int R){
if(l>R||r<L) return 0;
if(l>=L&&r<=R) return data[i];
pushdown(i);
int mid=l+r>>1;
return max(Query(i<<1,l,mid,L,R),Query(i<<1|1,mid+1,r,L,R));
}
void cdq(int l,int r){
if(r-l<1) return ;
int mid=l+r>>1,ii=l,x;
cdq(l,mid),cdq(mid+1,r);
sort(a+l,a+1+mid,cmp1);
sort(a+mid+1,a+r+1,cmp2);
//注意[l,mid][mid+1,r]排序方法不同
for(int j=mid+1;j<=r;j++){//cdq常规操作
while(ii<=mid&&a[ii].xl<=a[j].xr)
add(1,1,m,a[ii].yl,a[ii].yr,a[ii].xr),ii++;
f[a[j].id]|=(Query(1,1,m,a[j].yl,a[j].yr)>=a[j].xl);
//更新fj
}
data[1]=lz[1]=LZ[1]=0,pushdown(1);
//将整个区间打上清空懒标记
//不要忘记下传一层
}
map<int,int>Hx,Hy;
int main(){
n=read(),memset(LZ,-1,sizeof(LZ));
int x,y,u,v,cntx=0,cnty=0,Cntx=0,Cnty=0;
for(int i=1;i<=n;i++){
a[i].id=i,x=read()+1,y=read()+1,u=read(),v=read();
a[i].xl=x,a[i].yl=y,a[i].xr=x+u-1,a[i].yr=y+v-1;
X[++cntx]=a[i].xl,X[++cntx]=a[i].xr;
Y[++cnty]=a[i].yl,Y[++cnty]=a[i].yr;
}
sort(X+1,X+1+cntx),sort(Y+1,Y+1+cnty);
Hx[X[1]]=++Cntx,Hy[Y[1]]=++Cnty;
for(int i=2;i<=cntx;i++){
if(X[i]!=X[i-1]) Hx[X[i]]=++Cntx;
if(Y[i]!=Y[i-1]) Hy[Y[i]]=++Cnty;
}
for(int i=1;i<=n;i++){
//离散化(其实xl,xr是不用离散化的)
a[i].xl=Hx[a[i].xl],a[i].xr=Hx[a[i].xr];
a[i].yl=Hy[a[i].yl],a[i].yr=Hy[a[i].yr];
}
sort(a+1,a+1+n,cmp4),m=Cnty,cdq(1,n);
for(int i=1;i<=n;i++)
printf("%s\n",f[i]?"NE":"DA");
return 0;
}

祝 \(\text{AC}\)。

[COCI2018-2019#2] Sunčanje 题解的更多相关文章

  1. Comet OJ 2019 夏季欢乐赛题解

    Comet OJ 2019 夏季欢乐赛题解 我是来骗访问量的 A 完全k叉树 \(n\)个点的完全k叉树的直径. 直接做 B 距离产生美 直接做 C 烤面包片 \(n!!!\mod p\) 显然\(n ...

  2. 洛谷P5283 & LOJ3048:[十二省联考2019]异或粽子——题解

    https://www.luogu.org/problemnew/show/P5283 https://loj.ac/problem/3048 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子 ...

  3. kick start 2019 round D T3题解

    ---恢复内容开始--- 题目大意:共有N个房子,每个房子都有各自的坐标X[i],占据每个房子需要一定花费C[i].现在需要选择K个房子作为仓库,1个房子作为商店(与题目不同,概念一样),由于仓库到房 ...

  4. kick start 2019 round D T2题解

    题目大意:由N个房子围成一个环,G个人分别顺时针/逆时针在房子上走,一共走M分钟,每分钟结束,每个人顺/逆时针走到相邻的房子.对于每个房子都会记录最后时刻到达的人(可能是一群人).最终输出每个人会被几 ...

  5. 2019.11.11&12题解

    Day1 考的不是很好,T1T2没区分度,T3想的太少,考试后期几乎都是在摸鱼,bitset乱搞也不敢打,只拿到了35分,跟前面的差距很大 A. 最大或 标签: 二进制+贪心 题解: 首先x,y中一定 ...

  6. 2019.11.12&13题解

    写在前面: 虽然拿到了rk1,但是T3被卡常TLE90分,(考后再交就A了!?),lemon80,又丢失了一次良好的AK机会, 掐头去尾距离联赛仅剩2天,最近中午一直睡不好,可能是有些紧张, 希望自己 ...

  7. The Preliminary Contest for ICPC Asia Nanjing 2019/2019南京网络赛——题解

    (施工中……已更新DF) 比赛传送门:https://www.jisuanke.com/contest/3004 D. Robots(期望dp) 题意 给一个DAG,保证入度为$0$的点只有$1$,出 ...

  8. 【NOI 2019】同步赛 / 题解 / 感想

    非常颓写不动题怎么办…… 写下这篇博客警示自己吧…… 游记 7.16 我并不在广二参加 NOI,而是在距离广二体育馆一公里远的包间打同步赛(其实就是给写不动题找个理由) 上午身体不舒服,鸽了半天才看题 ...

  9. 2019 IEEEXtreme 13.0 题解记录

    比赛时间 2019.10.19 8:00 - 2019.10.20 8:00 比赛网站 https://csacademy.com/ieeextreme13 // 连续24小时做题真的是极限体验 // ...

随机推荐

  1. 快速沃尔什变换&快速莫比乌斯变换小记

    u1s1 距离省选只剩 5 days 了,现在学新算法真的合适吗(( 位运算卷积 众所周知,对于最普通的卷积 \(c_i=\sum\limits_{j+k=i}a_jb_k\),\(a_jb_k\) ...

  2. Atcoder Regular Contest 058 D - 文字列大好きいろはちゃん / Iroha Loves Strings(单调栈+Z 函数)

    洛谷题面传送门 & Atcoder 题面传送门 神仙题. mol 一发现场(bushi)独立切掉此题的 ycx %%%%%%% 首先咱们可以想到一个非常 naive 的 DP,\(dp_{i, ...

  3. 【GS文献】基因组选择技术在农业动物育种中的应用

    中国农业大学等多家单位2017年合作发表在<遗传>杂志上的综述,笔记之. 作者中还有李宁院士,不胜唏嘘. 1.概述 GS的两大难题:基因组分型的成本,基因组育种值(genomic esti ...

  4. R语言与医学统计图形【3】条形图、误差图

    R语言基础绘图系统 基础图形--条形图.误差图 3.条形图 barplot接收的数据是矩阵而非数据框. data <- sample(c(50:80),5) barplot(data,col=h ...

  5. MYSQL5.8---1

    主键不能为空,唯一键可以为空且可以多个唯一键 外键必须为另一个表中的主键 外键的用途是确保数据的完整性.它通常包括以下几种: 1 实体完整性,确保每个实体是唯一的(通过主键来实施) 2 域完整性,确保 ...

  6. Linux—yum的python版本错误——高级解决方案

    彻底搞明白,python升级后,为什么会导致yum不可用 首先我们来分析下,python升级后,yum为什么会不可用? 先说个关于python的问题,Linux系统很多软件都依赖于python,因此不 ...

  7. Oracle-怎么在表的特定位置增加列

    create table tmp as select ID,UserName,RealName,Sex,Tel,Addr from tabName;drop table tabName;rename ...

  8. Python文件复制shutil模块

    Python中shutil模块主要用于文件操作,如复制,属性判断等 1.copyfileobj,拷贝文件内容,将文件句柄赋给该方法 def copyfileobj(src, dst, length=1 ...

  9. 学习java的第十六天

    一.今日收获 1.完成了手册第二章没有验证完成的例题 2.预习了第三章的算法以及for语句与if语句的用法 二.今日难题 1.验证上出现问题,没有那么仔细. 2.第二章还有没有完全理解的问题 三.明日 ...

  10. A Child's History of England.10

    In the next reign, which was the reign of Edward, surnamed The Elder, who was chosen in council to s ...