题目


分析

考虑将询问和边权按 \(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]最小公倍数的更多相关文章

  1. 洛谷P3247 [HNOI2016]最小公倍数(分块 带撤销加权并查集)

    题意 题目链接 给出一张带权无向图,每次询问\((u, v)\)之间是否存在一条路径满足\(max(a) = A, max(b) = B\) Sol 这题居然是分块..想不到想不到..做这题的心路历程 ...

  2. 洛谷P3247 [HNOI2016]最小公倍数 [分块,并查集]

    洛谷 思路 显然,为了达到这个最小公倍数,只能走\(a,b\)不是很大的边. 即,当前询问的是\(A,B\),那么我们只能走\(a\leq A,b\leq B\)的边. 然而,为了达到这最小公倍数,又 ...

  3. [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集

    4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1474  Solved: 521[Submit][Stat ...

  4. 【简单数据结构】并查集--洛谷 P1111

    题目背景 AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数NN,和公路数MM,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你 ...

  5. bzoj2049 线段树 + 可撤销并查集

    https://www.lydsy.com/JudgeOnline/problem.php?id=2049 线段树真神奇 题意:给出一波操作,拆边加边以及询问两点是否联通. 听说常规方法是在线LCT, ...

  6. CodeForces892E 可撤销并查集/最小生成树

    http://codeforces.com/problemset/problem/892/E 题意:给出一个 n 个点 m 条边的无向图,每条边有边权,共 Q 次询问,每次给出 ki​ 条边,问这些边 ...

  7. BZOJ4358: permu(带撤销并查集 不删除莫队)

    题意 题目链接 Sol 感觉自己已经老的爬不动了.. 想了一会儿,大概用个不删除莫队+带撤销并查集就能搞了吧,\(n \sqrt{n} logn\)应该卡的过去 不过不删除莫队咋写来着?....跑去学 ...

  8. 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic

    本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...

  9. codeforces 892E(离散化+可撤销并查集)

    题意 给出一个n个点m条边的无向联通图(n,m<=5e5),有q(q<=5e5)个询问 每个询问询问一个边集{Ei},回答这些边能否在同一个最小生成树中 分析 要知道一个性质,就是权值不同 ...

  10. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

随机推荐

  1. RabbitMQ和RPC

    消息队列 消息队列中间件 (Message Queue Middleware,简称 MQ) 是指利用高效可靠的消息传递机制进行与平台无关的数据交流,它可以在分布式环境下扩展进程间的数据通信,并基于数据 ...

  2. Linux Cheat Sheet

  3. 如何实现十亿级离线 CSV 导入 Nebula Graph

    本文首发于 Nebula Graph Community 公众号 本次实践是基于业务需求及后续扩展,通过技术选型确定了 Nebula Graph 图数据库,首先需要验证 Nebula Graph 数据 ...

  4. 图像识别算法--VGG16

    前言:人类科技就是不断烧开水(发电).丢石头(航天等).深度学习就是一个不断解方程的过程(参数量格外大的方程) 本文内容: 1.介绍VGG16基本原理 2.VGG16 pytorch复现 图像识别算法 ...

  5. C++ //排序案列 //描述:将person自定义数据类型进行排序,Person中有属性 姓名,年龄,身高 //排序规则: 按照年龄进行的升序,如果年龄相同按照身高进行降序

    1 //排序案列 2 //描述:将person自定义数据类型进行排序,Person中有属性 姓名,年龄,身高 3 //排序规则: 按照年龄进行的升序,如果年龄相同按照身高进行降序 4 5 #inclu ...

  6. gRPC入门学习之旅(一)

    gRpc简介 gRPC 是Google公司开发的基于HTTP/2设计,面向移动的一个高性能.开源和通用的 RPC 框架,是一款语言中立.平台中立.开源的远程过程调用(RPC)系统. gRpc官网地址: ...

  7. 基于RocketMQ实现分布式事务

    背景 在一个微服务架构的项目中,一个业务操作可能涉及到多个服务,这些服务往往是独立部署,构成一个个独立的系统.这种分布式的系统架构往往面临着分布式事务的问题.为了保证系统数据的一致性,我们需要确保这些 ...

  8. 单词本z ctrl shift alt - tr踩踏 shi流出 al不同

    单词本z ctrl shift alt ctrl = control = 控制 con = com = 一起 tr- = 踩 踏 - 原始印欧语形式为 *der- contra = 相对,相反(一起踩 ...

  9. 音频信号质量的度量标准--MOS得分的由来

    早期语音质量的评价方式是凭主观的,人们在打通电话之后通过人耳来感知语音质量的好坏.1996年国际ITU组织在ITU-T P.800和P.830建议书开始制订相关的评测标准:MOS(Mean Opini ...

  10. 回声消除(Acoustic Echo Cancellation)中遇到的几个常见问题思考

    什么才是好的回声消除效果   个人的理解:好的回声消除算法,要满足两个条件:一个是回声确实被消除了,另外一个是麦克风采集到音频信号不能被消除,常见的就是人的声音信号.这个算法只是提供了一种方法,具体的 ...