BZOJ4537 : [Hnoi2016]最小公倍数
将边按$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]最小公倍数的更多相关文章
- [BZOJ4537][HNOI2016]最小公倍数(分块+并查集)
4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1687 Solved: 607[Submit][Stat ...
- [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集
4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1474 Solved: 521[Submit][Stat ...
- BZOJ4537 HNOI2016最小公倍数(莫队+并查集)
考虑边只有一种权值的简化情况.那么当且仅当两点可以通过边权<=x的边连通,且连通块内最大边权为x时,两点间存在路径max为x的路径.可以发现两种权值是类似的,当且仅当两点可以通过边权1<= ...
- 【BZOJ4537】[Hnoi2016]最小公倍数 分块
[BZOJ4537][Hnoi2016]最小公倍数 Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在 ...
- BZOJ 4537: [Hnoi2016]最小公倍数 [偏序关系 分块]
4537: [Hnoi2016]最小公倍数 题意:一张边权无向图,多组询问u和v之间有没有一条a最大为a',b最大为b'的路径(不一定是简单路径) 首先想到暴力做法,题目要求就是判断u和v连通,并查集 ...
- 【LG3247】[HNOI2016]最小公倍数
[LG3247][HNOI2016]最小公倍数 题面 洛谷 题解 50pts 因为拼凑起来的部分分比较多,所以就放一起了. 以下设询问的\(a,b\)为\(A,B\), 复杂度\(O(nm)\)的:将 ...
- 【bzoj4537】 Hnoi2016—最小公倍数
http://www.lydsy.com/JudgeOnline/problem.php?id=4537 (题目链接) 题意 给出一个${n}$个点${m}$条边的无向图,每条边有两个权值${a,b} ...
- 【 bzoj4537】HNOI2016 最小公倍数
首先将边按a的值分组,每$\sqrt{m}$一组. 对于每一组,将符合一组a的询问选出来,将这些询问和这一块之前的边(a一定小于这些询问)按b排序,然后交替插入,询问,对于一个询问,在当前块也有可能有 ...
- 4537: [Hnoi2016]最小公倍数
Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你 ...
随机推荐
- NYOJ题目874签到
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAswAAAIzCAIAAACbd9iBAAAgAElEQVR4nO3dPXLjSNou0G8T8rUQ2V
- Tomcat7配置数据源
http://www.cnblogs.com/ITtangtang/archive/2012/05/21/2511749.html
- Delphi中怎么结束线程(这个线程是定时执行的)(方案二)
上篇博客中提出了一个问题:怎么结束一个定时循环执行的线程,并给出了一个解决方案,但是又出现了一个问题,详细去参考上一篇博客. 然后出去撒了个尿,突然脑子里出现了一个想法(看来工作和思考久了,出去走走, ...
- Jquery自定义扩展方法(一)
jquery是一款流行的JS框架,自定义JS方法,封装到Jquery中,调用起来也挺方便的,怎么写Jquery扩展方法那,网上翻阅了一部分代码,其实也挺简单的: 方式一: (jQuery.fn.set ...
- linux环境下libevent的使用
step1:安装libevent yum install libevent step2: 代码入下: #include <sys/socket.h> #include <sys/ty ...
- 3-1创建Sql Sever数据库登录名
登录名:连接Sql Sever 服务器 数据库用户名: Sql Sever 的使用者 每个用来登录Sql Sever 的账户都是一个用户. 同一个数据库可以拥有多个用户,每一个用户也同时可以访问多个数 ...
- 使用Visual Studio Code开发AngularJS应用
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:VSC发布之后,尤其最近刚刚更新到0.3之后,社区出现了很多介绍VSC使用的好文章.比 ...
- android倒计时(整理)
android倒计时 用到CountDownTimer Android中文API(143) —— CountDownTimer 前言 本章内容android.os.CountDownTime章节,版本 ...
- android:layout_weight属性详解 (转)
在android开发中LinearLayout很常用,LinearLayout的内控件的android:layout_weight在某些场景显得非常重要,比如我们需要按比例显示.android并没用提 ...
- 在Asp.Net MVC中用Ajax回调后台方法
在Asp.Net MVC中用Ajax回调后台方法基本格式: var operData = ...; //传递的参数(action中定义的) var type = ...; //传递的参数(action ...