题解 洛谷 P6349 【[PA2011]Kangaroos】
先考虑对题目进行转化,我们称两个区间有交集为这两个区间能匹配,每个询问就是在序列中最长能连续匹配的长度。
对序列中的一个区间\([l,r]\)和询问的一个区间\([L,R]\),若满足\(L \leqslant r\)且\(l \leqslant R\),那么这两个区间是能匹配的。
可以将一个区间用点来表示,然后用\(K-D\ Tree\)来维护所有的询问区间,序列区间按顺序一个个去更新每个询问的匹配信息即可。
对\(K-D\ Tree\)中的维护一个矩形来考虑,比如下图的蓝色矩形为这个矩形。
当一个点落在红色矩形时,那么该点和矩形内的所有点都能匹配,对该矩形打上加法标记,使矩形内所有点的当前匹配数加一。
当一个点落在黄色矩形时,那么该点和矩形内的所有点都不能匹配,对该矩形打上清零标记,使矩形内所有点的当前匹配数清零。
同时记录一个点在整个过程中的历史最大匹配数,其即为最终一个点所对应询问的答案。
对一个矩形清空后,还会进行一系列对其匹配数增加的操作,但此时打上加法标记是错误的,所以给它打上一个赋值标记,打标记时增加赋值标记即可,同时记录下这阶段赋值标记的历史最大值,并用其去更新该点的历史最大匹配数。
标记比较多,有很多细节,具体实现看代码吧。
\(code:\)
#include<bits/stdc++.h>
#define maxn 400010
using namespace std;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,m,root,tot,type;
int cov[maxn],his[maxn],add[maxn],tag[maxn];
int ans[maxn],ma[maxn],cnt[maxn];
struct node
{
int l,r;
}p[maxn];
struct KD_tree
{
int d[2],mi[2],ma[2],ls,rs,id;
}t[maxn],dat[maxn];
bool cmp(const KD_tree &a,const KD_tree &b)
{
return a.d[type]<b.d[type];
}
void pushup(int x)
{
int ls=t[x].ls,rs=t[x].rs;
for(int i=0;i<=1;++i)
{
t[x].ma[i]=t[x].mi[i]=t[x].d[i];
if(ls)
{
t[x].ma[i]=max(t[x].ma[i],t[ls].ma[i]);
t[x].mi[i]=min(t[x].mi[i],t[ls].mi[i]);
}
if(rs)
{
t[x].ma[i]=max(t[x].ma[i],t[rs].ma[i]);
t[x].mi[i]=min(t[x].mi[i],t[rs].mi[i]);
}
}
}
void update(int x,int v)
{
cnt[x]+=v,ma[x]=max(ma[x],cnt[x]);
}
void pushadd(int x,int v)
{
update(x,v);
if(cov[x]) tag[x]+=v,his[x]=max(his[x],tag[x]);
else add[x]+=v;
}
void pushcov(int x)
{
if(!cov[x]) cov[x]=1,his[x]=0;
cnt[x]=tag[x]=0;
}
void pushtag(int x,int v1,int v2)
{
cov[x]=1,his[x]=max(his[x],v2);
cnt[x]=tag[x]=v1,ma[x]=max(ma[x],his[x]);
}
void pushdown(int x)
{
int ls=t[x].ls,rs=t[x].rs;
if(add[x])
{
pushadd(ls,add[x]),pushadd(rs,add[x]);
add[x]=0;
}
if(cov[x])
{
pushtag(ls,tag[x],his[x]),pushtag(rs,tag[x],his[x]);
cov[x]=tag[x]=0;
}
}
void build(int l,int r,int k,int &x)
{
x=++tot,type=k;
int mid=(l+r)>>1;
nth_element(dat+l+1,dat+mid+1,dat+r+1,cmp);
t[x]=dat[mid];
if(l<mid) build(l,mid-1,k^1,t[x].ls);
if(r>mid) build(mid+1,r,k^1,t[x].rs);
pushup(x);
}
bool in(KD_tree tr,int l,int r)
{
return tr.ma[0]<=r&&l<=tr.mi[1];
}
bool out(KD_tree tr,int l,int r)
{
return tr.mi[0]>r||l>tr.ma[1];
}
void modify(int x,int l,int r)
{
int ls=t[x].ls,rs=t[x].rs;
if(in(t[x],l,r))
{
pushadd(x,1);
return;
}
if(out(t[x],l,r))
{
pushcov(x);
return;
}
pushdown(x);
if(t[x].d[0]<=r&&l<=t[x].d[1]) update(x,1);
else cnt[x]=0;
if(ls) modify(ls,l,r);
if(rs) modify(rs,l,r);
}
void dfs(int x)
{
int ls=t[x].ls,rs=t[x].rs;
pushdown(x),ans[t[x].id]=ma[x];
if(ls) dfs(ls);
if(rs) dfs(rs);
}
int main()
{
read(n),read(m);
for(int i=1;i<=n;++i) read(p[i].l),read(p[i].r);
for(int i=1;i<=m;++i)
read(dat[i].d[0]),read(dat[i].d[1]),dat[i].id=i;
build(1,m,0,root);
for(int i=1;i<=n;++i) modify(root,p[i].l,p[i].r);
dfs(root);
for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
return 0;
}
题解 洛谷 P6349 【[PA2011]Kangaroos】的更多相关文章
- 洛谷 P6349 - [PA2011]Kangaroos(KDT+标记下放)
洛谷题面传送门 KDT 上打标记的 hot tea. 考虑将询问 \(A,B\) 看作二维平面直角坐标系上的一个点 \((A,B)\),那么我们这样考虑,我们从左到右扫过全部 \(n\) 个区间并开一 ...
- 题解 洛谷P5018【对称二叉树】(noip2018T4)
\(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- 题解-洛谷P4229 某位歌姬的故事
题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...
- 题解-洛谷P4724 【模板】三维凸包
洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...
- 题解-洛谷P4859 已经没有什么好害怕的了
洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...
- 题解-洛谷P5217 贫穷
洛谷P5217 贫穷 给定长度为 \(n\) 的初始文本 \(s\),有 \(m\) 个如下操作: \(\texttt{I x c}\),在第 \(x\) 个字母后面插入一个 \(c\). \(\te ...
- 题解 洛谷 P2010 【回文日期】
By:Soroak 洛谷博客 知识点:模拟+暴力枚举 思路:题目中有提到闰年然后很多人就认为,闰年是需要判断的其实,含有2月29号的回文串,前四位是一个闰年那么我们就可以直接进行暴力枚举 一些小细节: ...
随机推荐
- Linux上的Systemctl命令
LinuxSystemctl是一个系统管理守护进程.工具和库的集合,用于取代System V.service和chkconfig命令,初始进程主要负责控制systemd系统和服务管理器.通过Syste ...
- elk5
在百度指数上面可以看到二者热度的一个对比 es要先建立索引index,才能进行检索 elasticSearch的安装 1.jdk要1.8版本以上,并且每台elasticserach的jdk版本要一致 ...
- 黎活明8天快速掌握android视频教程--16_采用SharedPreferences保存用户偏好设置参数
SharedPreferences保存的数据是xml格式,也是存在数据保存的下面四种权限: 我们来看看 我们来看看具体的业务操作类: /** * 文件名:SharedPrecences.java * ...
- Python 简明教程 --- 6,Python 控制流
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io Talk is cheap, show me the code. -- Linus Torvalds ...
- 不就是语法和长难句吗—笔记总结Day4
第六课 英语的特殊结构 1.强调句型 It is...that / who / which(少见)... * 强调句型可以强调句子中所有成分(唯一不能强调谓语)* It is obviously t ...
- Spring 容器的初始化
读完这篇文章你将会收获到 了解到 Spring 容器初始化流程 ThreadLocal 在 Spring 中的最佳实践 面试中回答 Spring 容器初始化流程 引言 我们先从一个简单常见的代码入手分 ...
- Logstash7.6.2同步Mysql数据到ElasticSearch
1.准备工作:存在的mysql的数据库表.创建好的elasticsearch索引 2.下载mysql-connector 下载地址:https://dev.mysql.com/downloads/co ...
- Jmeter系列(37)- 详解 ForEach控制器
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 前言 ForEach 控制器一般和用户 ...
- css/html 空格,html空格符的显示、标示方式【html空格代码】
在html里面空格的话,你直接敲打出来的空格是不可以的,下面将通过html和css中设置显示空格的实现总结: Html中空格 符号 编号 描述 不断行的空白(1个字符宽度), 不换行空格 全 ...
- 「单调队列优化DP」P2034 选择数字
「单调队列优化DP」P2034 选择数字 题面描述: 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入格 ...