【BZOJ5005】乒乓游戏 [线段树][并查集]
乒乓游戏
Time Limit: 10 Sec Memory Limit: 256 MB
Description

Input

Output

Sample Input
5
1 1 5
1 5 11
2 1 2
1 2 9
2 1 2
Sample Output
NO
YES
HINT

Main idea
如果一个区间的端点在区间内,则这个区间可以走到那个区间,询问一个区间能否到另一个区间。
Source
首先我们立马想到了:如果两个区间严格有交集,那么这两个区间所能到达的区间集合是一样的。那么如果两个区间严格有交集的话我们就可以把它们合并起来,这里运用并查集。
这样处理完之后,剩下的区间只有两种情况:包含或者相离。那么查询的时候显然只要判断两个区间指向的大区间的情况即可。
我们要怎么合并呢?显然就是在线段树上进行操作,对于线段树上的每个节点开个vector,存下严格包含这个节点表示的[l,r]的区间的编号,那么我们加入新区间的时候,只要把左右端点在线段树上往下走,如果遇到这个线段树上的节点上的vector有东西,就记录几个区间的最小左端点以及最大右端点,把这几个区间的父亲都指向这个新区间,再删除掉这几个区间即可。然后合并完之后,把得到的新区间再放到各个点的vector进去。
最后,由于这题区间端点权比较大,所以要先离散化。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
using namespace std; const int ONE=*;
const int INF=1e9+; int n;
int Num,cnt; vector <int> Node[ONE]; struct power
{
int l,r,opt;
}a[ONE],interval[ONE]; int Q[ONE],li_num;
struct LISAN
{
int pos,val;
}Li[ONE]; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} namespace LI
{
void add(int i)
{
if(a[i].opt!=) return;
Num++;
Li[++li_num].val = a[i].l; Li[li_num].pos = li_num;
Li[++li_num].val = a[i].r; Li[li_num].pos = li_num;
} int cmp(const LISAN &a,const LISAN &b) {return a.val < b.val;}
void Lisan()
{
sort(Li+, Li+li_num+, cmp); cnt=;
Li[].val=-INF;
for(int i=;i<=li_num;i++)
{
if(Li[i].val!=Li[i-].val) ++cnt;
Q[Li[i].pos]=cnt;
}
Num=cnt; cnt=;
for(int i=;i<=n;i++)
if(a[i].opt==)
a[i].l=Q[++cnt], a[i].r=Q[++cnt]; }
} int fat[ONE];
int Find(int x)
{
if(fat[x]==x) return x;
return fat[x]=Find(fat[x]);
} namespace Seg
{
void Delete(int i,int l,int r,int L)
{
if(Node[i].size())
{
for(int j=; j<Node[i].size(); j++)
{
int id=Node[i][j];
fat[ Find(id) ] = cnt;
interval[cnt].l = min(interval[cnt].l, interval[id].l);
interval[cnt].r = max(interval[cnt].r, interval[id].r);
}
Node[i].clear();
}
if(l==r) return;
int mid = (l+r)>>;
if(L <= mid) Delete(i<<, l, mid, L);
else Delete(i<<|, mid+, r, L);
} void Update(int i,int l,int r,int L,int R)
{
if(L>R) return;
if(L<=l && r<=R)
{
Node[i].push_back(cnt);
return;
}
int mid=(l+r)>>;
if(L<=mid) Update(i<<,l,mid,L,R);
if(mid+<=R) Update(i<<|,mid+,r,L,R);
}
} bool P_edge(power a,power b)
{
if( (b.l<a.l && a.l<b.r) || (b.l<a.r && a.r<b.r)) return ;
return ;
} int main()
{
n=get();
for(int i=;i<=n;i++)
{
a[i].opt=get();
a[i].l=get(); a[i].r=get();
LI::add(i);
}
for(int i=;i<=Num;i++) fat[i]=i; LI::Lisan(); cnt=;
for(int i=;i<=n;i++)
{
if(a[i].opt==)
{
interval[++cnt] = a[i];
Seg::Delete(,,Num, a[i].l);
Seg::Delete(,,Num, a[i].r);
Seg::Update(,,Num, interval[cnt].l+,interval[cnt].r-);
}
else
{
int x=Find(a[i].l), y=Find(a[i].r);
if(x==y || P_edge(interval[x] , interval[y]))
printf("YES\n");
else
printf("NO\n");
}
}
}
【BZOJ5005】乒乓游戏 [线段树][并查集]的更多相关文章
- [WC2005]双面棋盘(线段树+并查集)
线段树+并查集维护连通性. 好像 \(700ms\) 的时限把我的常数超级大的做法卡掉了, 必须要开 \(O_2\) 才行. 对于线段树的每一个结点都开左边的并查集,右边的并查集,然后合并. \(Co ...
- 2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集)
2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集) https://www.luogu.com.cn/problem/CF811E Ste ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- 【XSY2707】snow 线段树 并查集
题目描述 有\(n\)个人和一条长度为\(t\)的线段,每个人还有一个工作范围(是一个区间).最开始整条线段都是白的.定义每个人的工作长度是这个人的工作范围中白色部分的长度(会随着线段改变而改变).每 ...
- bzoj 2054: 疯狂的馒头(线段树||并查集)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2054 线段树写法: 点的颜色只取决于最后一次染的颜色,所以我们可以倒着维护,如果当前区间之前 ...
- 【CF687D】Dividing Kingdom II 线段树+并查集
[CF687D]Dividing Kingdom II 题意:给你一张n个点m条边的无向图,边有边权$w_i$.有q个询问,每次给出l r,问你:如果只保留编号在[l,r]中的边,你需要将所有点分成两 ...
- 【BZOJ1453】[Wc]Dface双面棋盘 线段树+并查集
[BZOJ1453][Wc]Dface双面棋盘 Description Input Output Sample Input Sample Output HINT 题解:话说看到题的第一反应其实是LCT ...
- codeforces 811E Vladik and Entertaining Flags(线段树+并查集)
codeforces 811E Vladik and Entertaining Flags 题面 \(n*m(1<=n<=10, 1<=m<=1e5)\)的棋盘,每个格子有一个 ...
- 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]
Vladik and Entertaining Flags Time Limit: 20 Sec Memory Limit: 512 MB Description n * m的矩形,每个格子上有一个 ...
随机推荐
- Android Stadio 指定文件打开类型
我们项目里面,有一个文件,叫做aaa.meta. 这个只是一个配置文件,里面是txt. 但是Android Stadio 不识别.怎么办? 设置如下图: 首先,打开Android stadio 的设置 ...
- Objective-C反射机制
oc反射机制有三个用途: 1.获得Class Class LoginViewController = NSClassFromString(@"LoginViewController" ...
- 原生js实现五子棋
为什突然做这个,因为这是个笔试题,拖了一个月才写(最近终于闲了O(∩_∩)O),废话不多说,说说这个题吧 题目要求 编写一个单机[五子棋]游戏,要求如下: 1.使用原生技术实现,兼容 Chrome 浏 ...
- vue2.0 watch
类型:string | Function | Object vue官网解释: 一个对象,键是需要观察的表达式,值是对应回调函数.值也可以是方法名,或者包含选项的对象.Vue 实例将会在实例化时调用 $ ...
- Qt Qwdget 汽车仪表知识点拆解8 淡入效果
先贴上效果图,注意,没有写逻辑,都是乱动的 看下面的开始,开始的时候有一个带入的效果,这里有一个坑, 网上大部分都是调用下面这个函数 setWindowOpacity(); 但是,你会发现,在你的子窗 ...
- Qt 实现在隐藏标题栏情况下,窗口的缩放(未成功)
呃,这是一个悲剧的版本,在这版本中,我按照网上大神的说法,试了一下,但是没有效果,不知道出错在了那里,和昨天一样,也是,没有理想的效果,这里贴上代码,记录一下 资料连接:放评论 需要包含头文件 #in ...
- Qt Creater 制作汽车仪表盘
最近项目用到了模拟仪表,网上下载大神编写的按个仪表Meter没有成功 转战 QWt 编译后,在creater中仍然无法使用,只可以在代码中使用 百度说是我编译的版本不对 扔到 开始做自己的 这个用到了 ...
- 算法搬运之BFPRT算法
原文连接:http://noalgo.info/466.html BFPRT算法,又称为中位数的中位数算法,由5位大牛(Blum . Floyd . Pratt . Rivest . Tarjan)提 ...
- NMON记录服务器各项性能数据
1.将下载下来的nmon文件通过ftp传入服务器下,将nmon权限全开chmod +x nmon 2.查看nmon可以看到如下内容 查看各项指标 输入C,CPU数据 M,内存 N,网络 D,磁盘 T, ...
- bam文件测序深度统计-bamdst
最近接触的数据都是靶向测序,或者全外测序的数据.对数据的覆盖深度及靶向捕获效率的评估成为了数据质量监控中必不可少的一环. 以前都是用samtools depth 算出单碱基的深度后,用perl来进行深 ...