#分块,可撤销并查集#洛谷 3247 [HNOI2016]最小公倍数
分析
考虑将询问和边权按 \(a\) 分别从小到大排序,考虑最暴力的做法就是将不超过 \(a'\) 且 不超过 \(b'\) 的边抽取出来
放进并查集判断 \(a,b\) 的最大值都能达到 \(a',b'\),并查集可以撤销,这样就做到 \(O(qm\log n)\)
考虑让边尽量减小抽取的次数,将边每 \(B\) 个分一段,那么询问实际上也会分段,
之前段的所有边可以用归并排序按照 \(b\) 排序,用双指针加入并查集。
当前段的边只有 \(B\) 条,每次完成一个询问后撤销操作,
\(O(qB\log n+\frac{m^2}{B}\log n)\),理论上取 \(B=\sqrt{\frac{m^2}{q}}\) 时最优,
实际上取 \(B=\sqrt{m\log{n}}\) 就可以跑得飞快了
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cmath>
#define rr register
using namespace std;
const int N=50011,M=100011;
struct four{int x,y,a,b;}e[M],E[M],q[N];
int b[N],f[N],dep[N],mxa[N],mxb[N],yea[M],yeb[M],yed[M],yex[M],yey[M],Top,n,m,Q,block,rk[N],ans[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
bool cmp1(four x,four y){return x.a<y.a||(x.a==y.a&&x.b<y.b);}
bool cmp2(int x,int y){return q[x].b<q[y].b||(q[x].b==q[y].b&&q[x].a<q[y].a);}
bool cmp3(four x,four y){return x.b<y.b||(x.b==y.b&&x.a<y.a);}
inline void Clear(){for (rr int i=1;i<=n;++i) mxa[i]=mxb[i]=-1,f[i]=i,dep[i]=1;}
inline signed max(int a,int b){return a>b?a:b;}
inline signed getf(int u){return f[u]==u?u:getf(f[u]);}
inline void uni(four t){
rr int fa=getf(t.x),fb=getf(t.y);
if (dep[fa]<dep[fb]) fa^=fb,fb^=fa,fa^=fb;
++Top,yex[Top]=fa,yey[Top]=fb,yea[Top]=mxa[fa],yeb[Top]=mxb[fa],yed[Top]=dep[fa];
if (fa!=fb) f[fb]=fa,mxa[fa]=max(mxa[fa],mxa[fb]),mxb[fa]=max(mxb[fa],mxb[fb]);
mxa[fa]=max(mxa[fa],t.a),mxb[fa]=max(mxb[fa],t.b);
if (fa!=fb&&dep[fa]==dep[fb]) ++dep[fa];
}
inline void Trace(){
for (rr int i=Top;i;--i)
f[yey[i]]=yey[i],mxa[yex[i]]=yea[i],mxb[yex[i]]=yeb[i],dep[yex[i]]=yed[i];
}
inline void Merge(int l,int r){
sort(e+l,e+r,cmp3);
rr int lj=1,lk=l,tot=0;
while (lj<l&&lk<r)
if (e[lj].b<e[lk].b||(e[lj].b==e[lk].b&&e[lj].a<e[lk].b))
E[++tot]=e[lj++];
else E[++tot]=e[lk++];
while (lj<l) E[++tot]=e[lj++];
while (lk<r) E[++tot]=e[lk++];
for (rr int i=1;i<=tot;++i) e[i]=E[i];
}
signed main(){
n=iut(),m=iut(),block=sqrt(m*log2(n));
for (rr int i=1;i<=m;++i)
e[i]=(four){iut(),iut(),iut(),iut()};
Q=iut();
for (rr int i=1;i<=Q;++i)
q[i]=(four){iut(),iut(),iut(),iut()},rk[i]=i;
sort(e+1,e+1+m,cmp1),sort(rk+1,rk+1+Q,cmp2);
for (rr int i=1,nn,mn;i<=m;i+=block){
Clear(),nn=0,mn=(i+block>m)?(m+1):(i+block);
for (rr int j=1;j<=Q;++j)
if (e[i].a<=q[rk[j]].a&&(i+block>m||q[rk[j]].a<e[i+block].a))
b[++nn]=rk[j];
for (rr int j=1,o=1;j<=nn;++j){
rr four t=q[b[j]];
for (;o<i&&e[o].b<=t.b;++o) uni(e[o]); Top=0;
for (rr int p=i;p<mn;++p)
if (e[p].a<=t.a&&e[p].b<=t.b) uni(e[p]);
rr int fa=getf(t.x),fb=getf(t.y);
ans[b[j]]=(fa==fb)&&(mxa[fa]==t.a)&&(mxb[fb]==t.b);
Trace();
}
Merge(i,mn);
}
for (rr int i=1;i<=Q;++i) puts(ans[i]?"Yes":"No");
return 0;
}
#分块,可撤销并查集#洛谷 3247 [HNOI2016]最小公倍数的更多相关文章
- 洛谷P3247 [HNOI2016]最小公倍数(分块 带撤销加权并查集)
题意 题目链接 给出一张带权无向图,每次询问\((u, v)\)之间是否存在一条路径满足\(max(a) = A, max(b) = B\) Sol 这题居然是分块..想不到想不到..做这题的心路历程 ...
- 洛谷P3247 [HNOI2016]最小公倍数 [分块,并查集]
洛谷 思路 显然,为了达到这个最小公倍数,只能走\(a,b\)不是很大的边. 即,当前询问的是\(A,B\),那么我们只能走\(a\leq A,b\leq B\)的边. 然而,为了达到这最小公倍数,又 ...
- [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集
4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1474 Solved: 521[Submit][Stat ...
- 【简单数据结构】并查集--洛谷 P1111
题目背景 AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数NN,和公路数MM,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你 ...
- bzoj2049 线段树 + 可撤销并查集
https://www.lydsy.com/JudgeOnline/problem.php?id=2049 线段树真神奇 题意:给出一波操作,拆边加边以及询问两点是否联通. 听说常规方法是在线LCT, ...
- CodeForces892E 可撤销并查集/最小生成树
http://codeforces.com/problemset/problem/892/E 题意:给出一个 n 个点 m 条边的无向图,每条边有边权,共 Q 次询问,每次给出 ki 条边,问这些边 ...
- BZOJ4358: permu(带撤销并查集 不删除莫队)
题意 题目链接 Sol 感觉自己已经老的爬不动了.. 想了一会儿,大概用个不删除莫队+带撤销并查集就能搞了吧,\(n \sqrt{n} logn\)应该卡的过去 不过不删除莫队咋写来着?....跑去学 ...
- 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic
本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...
- codeforces 892E(离散化+可撤销并查集)
题意 给出一个n个点m条边的无向联通图(n,m<=5e5),有q(q<=5e5)个询问 每个询问询问一个边集{Ei},回答这些边能否在同一个最小生成树中 分析 要知道一个性质,就是权值不同 ...
- 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)
题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...
随机推荐
- [攻防世界][江苏工匠杯]file_include
打开靶机url,上来就是代码审计 <?php highlight_file(__FILE__); include("./check.php"); if(isset($_GET ...
- 【译】代码更快、更好,借助 GitHub Copilot 的新功能:斜杠命令和上下文变量
你是否曾经希望有一个人工智能助手可以帮助你更快更好地编写代码?那就是 Visual Studio Copilot Chat 为您提供的:一个人工智能驱动的结对程序员,可以回答您的问题,建议代码片段,解 ...
- 项目实战:Qt+iMax6生命探测仪(探测障碍物、静止目标、动态目标、生命目标、探测半径、探测前方雷达显示、动态目标轨迹显示、探测热力图、探测过程存储与回放)
若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/110994486长期持续带来更多项目与技术分享, ...
- 进程,join的使用,守护进程---day30
1.进程 # ### 进程 import os,time #当前进程id(子进程) res = os.getpid() print(res) #1772 #当前进程id(父进程) res = os.g ...
- Kotlin return@xxx 的坑
Kotlin Return 到标签 先看例子: (1..5).forEach { if (it == 3) { return@forEach } println(it) } println(" ...
- 【WiFi开发全攻略】WIFI基础知识大全
[WiFi开发全攻略]WIFI基础知识大全 1. Wi-Fi起源 现在我们大家对Wi-Fi肯定都不陌生,无论是笔记本,手机,智能电视,都离不开Wi-Fi.目前我们一般用的都是Wi-Fi5,Wi-Fi6 ...
- Android Compose开发
目录 好处 入门 Composable 布局 其他组件 列表 verticalScroll 延迟列表 内容内边距 性能 修饰符 偏移量 requiredSize 滚动 添加间距Spacer Butto ...
- 【Azure Developer】在Azure Storage Account的两个Blob可以同步吗?可以跨订阅拷贝吗?
问题描述 不同订阅下的Azure Storage Account中Blob资源可以同步吗? 解决方案 可以.通过Azure 官方推荐的Storage Account工具来完成 Copy/Paste 操 ...
- debian手册摘要
apt-get source 包名 # 获取源码dpkg --info deb包名 # 查看包信息apt-cache show 包名 # 包信息(含有Depends.Suggests.Section. ...
- 「实操」适配 NebulaGraph 新版本与压测实践
本文来自邦盛科技-知识图谱团队-繁凡,本文以 NebulaGraph v3.1.0 为例. 前言 NebulaGraph v3.1 版本已经发布有一段时间了,但是我们的项目之前是基于 v2.6.1 版 ...