将边按$a$从小到大排序,每$\sqrt{m}$个取一个关键点。

对于每个关键点,将这个点之前的边以及要在这个关键点回答的询问按$b$排序。

依次加入这个关键点之前的每条边,用并查集维护每个连通块$a$和$b$的最大值。

对于零碎部分,只有$\sqrt{m}$条边,暴力加入即可。

用一个栈按时间记录所有修改操作,然后撤销操作即可。

时间复杂度$O(m\sqrt{m}\log n)$。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=50010,M=100010;
int n,m,Q,lim,i,j,k,o,x,y,ans[N],cnt,a[M],b[N];
int f[N],d[N],va[N],vb[N],co;
struct P{int x,y,z;P(){}P(int _x,int _y,int _z){x=_x,y=_y;z=_z;}}op[N];
struct E{int x,y,a,b;}e[M],q[N];
inline bool cmpa(const E&a,const E&b){return a.a<b.a;}
inline bool cmpe(int x,int y){return e[x].b<e[y].b;}
inline bool cmpq(int x,int y){return q[x].b<q[y].b;}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
int F(int x){return f[x]==x?x:F(f[x]);}
inline void merge(int x,int y,int a,int b,int type){
x=F(x),y=F(y);
if(x!=y){
if(d[x]==d[y]){
if(type)op[++co]=P(1,x,d[x]);
d[x]++;
}
if(d[x]<d[y])swap(x,y);
if(type)op[++co]=P(0,y,y);
f[y]=x;
if(va[x]<va[y]&&va[y]>a){
if(type)op[++co]=P(2,x,va[x]);
va[x]=va[y];
}
if(vb[x]<vb[y]&&vb[y]>b){
if(type)op[++co]=P(3,x,vb[x]);
vb[x]=vb[y];
}
}
if(va[x]<a){
if(type)op[++co]=P(2,x,va[x]);
va[x]=a;
}
if(vb[x]<b){
if(type)op[++co]=P(3,x,vb[x]);
vb[x]=b;
}
}
inline void retrace(){
for(int i=co;i;i--){
if(!op[i].x)f[op[i].y]=op[i].z;
else if(op[i].x==1)d[op[i].y]=op[i].z;
else if(op[i].x==2)va[op[i].y]=op[i].z;
else vb[op[i].y]=op[i].z;
}
co=0;
}
int main(){
read(n),read(m);
while(lim*lim<m)lim++;
for(i=1;i<=m;i++)read(e[i].x),read(e[i].y),read(e[i].a),read(e[i].b),a[i]=i;
sort(e+1,e+m+1,cmpa);
read(Q);
for(i=1;i<=Q;i++)read(q[i].x),read(q[i].y),read(q[i].a),read(q[i].b);
for(i=0;i<=m;i+=lim){
cnt=0;
for(j=1;j<=Q;j++)if(q[j].a>=e[i].a&&(i+lim>m||q[j].a<e[i+lim].a))b[++cnt]=j;
if(!cnt)continue;
sort(a+1,a+i+1,cmpe);
sort(b+1,b+cnt+1,cmpq);
for(j=1;j<=n;j++)f[j]=j,d[j]=0,va[j]=vb[j]=-1;
for(j=k=1;j<=cnt;j++){
while(k<=i&&e[a[k]].b<=q[b[j]].b){
merge(e[a[k]].x,e[a[k]].y,e[a[k]].a,e[a[k]].b,0);
k++;
}
co=0;
for(o=min(i+lim-1,m);o>i;o--)
if(e[o].a<=q[b[j]].a&&e[o].b<=q[b[j]].b)
merge(e[o].x,e[o].y,e[o].a,e[o].b,1);
x=F(q[b[j]].x),y=F(q[b[j]].y);
if(x==y&&va[x]==q[b[j]].a&&vb[x]==q[b[j]].b)ans[b[j]]=1;
retrace();
}
}
for(i=1;i<=Q;i++)puts(ans[i]?"Yes":"No");
return 0;
}

  

BZOJ4537 : [Hnoi2016]最小公倍数的更多相关文章

  1. [BZOJ4537][HNOI2016]最小公倍数(分块+并查集)

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

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

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

  3. BZOJ4537 HNOI2016最小公倍数(莫队+并查集)

    考虑边只有一种权值的简化情况.那么当且仅当两点可以通过边权<=x的边连通,且连通块内最大边权为x时,两点间存在路径max为x的路径.可以发现两种权值是类似的,当且仅当两点可以通过边权1<= ...

  4. 【BZOJ4537】[Hnoi2016]最小公倍数 分块

    [BZOJ4537][Hnoi2016]最小公倍数 Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在 ...

  5. BZOJ 4537: [Hnoi2016]最小公倍数 [偏序关系 分块]

    4537: [Hnoi2016]最小公倍数 题意:一张边权无向图,多组询问u和v之间有没有一条a最大为a',b最大为b'的路径(不一定是简单路径) 首先想到暴力做法,题目要求就是判断u和v连通,并查集 ...

  6. 【LG3247】[HNOI2016]最小公倍数

    [LG3247][HNOI2016]最小公倍数 题面 洛谷 题解 50pts 因为拼凑起来的部分分比较多,所以就放一起了. 以下设询问的\(a,b\)为\(A,B\), 复杂度\(O(nm)\)的:将 ...

  7. 【bzoj4537】 Hnoi2016—最小公倍数

    http://www.lydsy.com/JudgeOnline/problem.php?id=4537 (题目链接) 题意 给出一个${n}$个点${m}$条边的无向图,每条边有两个权值${a,b} ...

  8. 【 bzoj4537】HNOI2016 最小公倍数

    首先将边按a的值分组,每$\sqrt{m}$一组. 对于每一组,将符合一组a的询问选出来,将这些询问和这一块之前的边(a一定小于这些询问)按b排序,然后交替插入,询问,对于一个询问,在当前块也有可能有 ...

  9. 4537: [Hnoi2016]最小公倍数

    Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你 ...

随机推荐

  1. Android xml text 预览属性

    只在 AS 中生效 xmlns:tools="http://schemas.android.com/tools" tools:text="I am a title&quo ...

  2. 与你相遇好幸运,Tippecanoe用法

    //todo 基本用法: tippecanoe -o file.mbtiles [file.json ...] 参数解释: <必须>   -o myFileName.mbtiles  或者 ...

  3. ASP.NET Web API中使用GZIP 或 Deflate压缩

    对于减少响应包的大小和响应速度,压缩是一种简单而有效的方式. 那么如何实现对ASP.NET Web API 进行压缩呢,我将使用非常流行的库用于压缩/解压缩称为DotNetZip库.这个库可以使用Nu ...

  4. 微软MSMQ消息队列的使用

    首先在windows系统中安装MSMQ 一.MSMQ交互 开发基于消息的应用程序从队列开始.MSMQ包含四种队列类型: 外发队列:消息发送到目的地之前,用它来临时存储消息. 公共队列:在主动目录中公布 ...

  5. Linux中带颜色输出的printf使用简介(\033)

    昨晚懒得FQ, 百度了一下linux中printf输出颜色的方法, 结果搜索结果质量让人倍感伤心. 越来越不想用bd了.还是Google一下吧, 手气真好, 第一个内容就很清楚明了! 我还是直接简单翻 ...

  6. PHP不同域名cookie共享(单点登录实现原理)

    PHP使用P3P完成COOKIE跨域操作实际实用中,类似的需求有,比如说我们有两个域名,我们想实现在一个域名登录后,能自动完成另一个域名的登录,也就是单点登录(SSO)功能.为了测试的方便,先编辑ho ...

  7. angularJS 二

    angularJS 2.1  ngForm <!DOCTYPE html> <html lang="zh-cn" ng-app> <head> ...

  8. 等号赋值与memcpy的效率问题

    转自:http://www.aiuxian.com/article/p-1309055.html 偶尔看到一个说法,说,小内存的拷贝,使用等号直接赋值比memcpy快得多.结合自己搜集到的资料,整理成 ...

  9. win10 Edge浏览器一打开就闪退崩溃的解决思路

    故障现象:从Win7.Win8.1升级到Win10,或是使用Win10一段时间后,发现Edge浏览器打开一到两秒就闪退,崩溃无法打开.解决方案: 1.尝试清理: C:\Users\Administra ...

  10. fatal error C1083: 无法打开包括文件:“stddef.h”: No such file or directory

      在VS2012安装吗目录下的这个文件夹 D:\Program Files\Visual Studio 2012\VC\include 找到了stddef.h文件,将其加到项目的包含目录中,OK. ...