给定一张N个顶点M条边的无向图 每条边上带有权值 所有权值都可以分解成2^a*3^b的形式

q个询问,每次询问给定四个参数u、v、a和b,请你求出是否存在一条顶点u到v之间的路径,使得路径依次经过的边上的权值的最小公倍数为2^a*3^b

注意:路径可以不是简单路径

下面是一些可能有用的定义:

最小公倍数:K个数a1,a2,…,ak的最小公倍数是能被每个ai整除的最小正整数

路径:路径P:P1,P2,…,Pk是顶点序列,满足对于任意1<=i<k,节点Pi和Pi+1之间都有边相连

简单路径:如果路径P:P1,P2,…,Pk中,对于任意1<=s≠t<=k都有Ps≠Pt,那么称路径为简单路径

思路:

对于每个询问(u,v,A,B),将a<=A和b<=B的边全部加入并查集中,最后判断u和v是否在同一连通分量中且连通分量包含的最大的a=A,最大的b=B即可

把询问和边离线按a排序,询问时在已经加入的边中按b值排序加入并查集中

结合起来,按a值将询问和边分块,前面的边按第二种做法做,块内的边按第一种做法做就行了

因为并查集需要支持撤销,所以要用按秩合并
 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 2139062143
#define ll long long
#define MAXN 100100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,T,fa[MAXN],rnk[MAXN],f,pos,b,mxp[MAXN],mxq[MAXN],top,cnt,size,ans[MAXN];
struct data
{
int u,v,p,q,pos;
bool operator < (const data & a) const {return q<a.q||(q==a.q&&pos<a.pos);}
}qs[MAXN],e[MAXN<<],tmp[MAXN<<];
struct stck{int u,v,rnk,p,q;}st[MAXN<<];
int find(int x) {return x==fa[x]?x:find(fa[x]);}
void merge(int u,int v,int p,int q)
{
int x=find(u),y=find(v);
if(rnk[x]<rnk[y]) swap(x,y);
st[++top]=(stck) {x,y,rnk[x],mxp[x],mxq[x]};
fa[y]=x;
mxp[x]=max(p,max(mxp[y],mxp[x]));
mxq[x]=max(q,max(mxq[x],mxq[y]));
if(rnk[x]==rnk[y]) rnk[x]++;
}
bool Cmp(data a,data b) {return a.p<b.p||(a.p==b.p&&a.q<b.q);}
void dlt()
{
fa[st[top].v]=st[top].v,rnk[st[top].u]=st[top].rnk,mxp[st[top].u]=st[top].p,mxq[st[top].u]=st[top].q,top--;
}
int main()
{
//freopen("al.in","r",stdin);
//freopen("al.out","w",stdout);
n=read(),m=read();int x,y,tot=;
for(int i=;i<=m;i++)
e[i].u=read(),e[i].v=read(),e[i].p=read(),e[i].q=read(),e[i].pos=;
size=sqrt(m*);
sort(e+,e+m+,Cmp);
T=read();
for(int i=;i<=T;i++)
qs[i].u=read(),qs[i].v=read(),qs[i].p=read(),qs[i].q=read(),qs[i].pos=i;
sort(qs+,qs+T+,Cmp);
for(int i=;i<=m;i++)
{
if((++tot==size)||i==m)
{
cnt=;
for(int j=;j<=i-tot;j++) tmp[++cnt]=e[j];
for(int j=;j<=T;j++)
if(qs[j].p>=e[i-cnt+].p&&(i==m||qs[j].p<e[i+].p)) tmp[++cnt]=qs[j];
if(i-tot!=cnt)
{
for(int j=;j<=n;j++) fa[j]=j,rnk[j]=,mxp[j]=mxq[j]=-;
sort(tmp+,tmp+cnt+);top=;
for(int j=;j<=cnt;j++)
{
if(tmp[j].pos)
{
for(int k=i-tot+;k<=i+;k++)
{
if(e[k].p>tmp[j].p||k>i)
{
int x=find(tmp[j].u),y=find(tmp[j].v);
if(x==y&&mxp[x]==tmp[j].p&&mxq[x]==tmp[j].q) ans[tmp[j].pos]=;
for(int l=i-tot+;l<=k-;l++) if(e[l].q<=tmp[j].q) dlt();
break;
}
if(e[k].q<=tmp[j].q) merge(e[k].u,e[k].v,e[k].p,e[k].q);
}
}
else merge(tmp[j].u,tmp[j].v,tmp[j].p,tmp[j].q);
}
}
tot=;
}
}
for(int i=;i<=T;i++)
puts(ans[i]?"Yes":"No");
}

bzoj 4537 最小公倍数的更多相关文章

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

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

  2. bzoj 4537 HNOI2016 最小公倍数

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

  3. [BZOJ 4537][Hnoi 2016]最小公倍数

    传送门 并查集+分块 看到题目可以想到暴力做法, 对于每个询问, 将所有a和b小于等于询问值的的边加入图中(用并查集), 如果询问的u和v在一个联通块中, 且该联通块的maxa和maxb均等与询问的a ...

  4. bzoj 4537: [Hnoi2016]最小公倍数 分块+并查集

    题目大意: 给定一张n个点m条边的无向图,每条边有两种权.每次询问某两个点之间是否存在一条路径上的边的两种权的最大值分别等于给定值. n,q <= 50000. m <= 100000 题 ...

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

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

  6. 【BZOJ】【1025】【SCOI2009】游戏

    DP/整数拆分 整个映射关系可以分解成几个循环(置换群的预备知识?),那么总行数就等于各个循环长度的最小公倍数+1(因为有个第一行的1~N).那么有多少种可能的排数就等于问有多少种可能的最小公倍数. ...

  7. 【BZOJ】【2154】Crash的数字表格

    莫比乌斯反演 PoPoQQQ讲义第4题 题解:http://www.cnblogs.com/jianglangcaijin/archive/2013/11/27/3446169.html 感觉两次sq ...

  8. 【莫比乌斯反演】关于Mobius反演与lcm的一些关系与问题简化(BZOJ 2154 crash的数字表格&&BZOJ 2693 jzptab)

    BZOJ 2154 crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b ...

  9. [BZOJ 1025] [SCOI2009] 游戏 【DP】

    题目链接:BZOJ - 1025 题目分析 显然的是,题目所要求的是所有置换的每个循环节长度最小公倍数的可能的种类数. 一个置换,可以看成是一个有向图,每个点的出度和入度都是1,这样整个图就是由若干个 ...

随机推荐

  1. CAD在网页中绘图,并为新绘的对象写扩展数据和读取扩展数据

    在网页中绘图,并为新绘的对象写扩展数据和读取扩展数据.下面帮助的完整例子,在控件安装目录的 Sample\Ie\iedemo.htm 中. 主要用到函数说明: _DMxDrawX::InsertBlo ...

  2. Pycharm中通过扩展工具添加QTDesigner

    1.在电脑中找到Designer.exe的安装目录: 2.在pycharm中打开file->Settings->Tools->External Tools进行配置: 配置如下图所示: ...

  3. 话说Form标签的target属性-----无刷新表单提交

    国庆前(2013)无聊,就在铁道部的12306上“逛”了下下. PS:原来之所以叫12306,是因为其客服号码是12306,好吧,我很无知…… 首先是被“逛”的页面:票价查询. 之所以去逛,是因为一直 ...

  4. cc.Node—场景树

    对于cc.Node我分了四个模块学习: 1.场景树,2.事件响应,3.坐标系统,4.Action的使用:在此记录经验分享给大家. 场景树 1: creator是由一个一个的游戏场景组成,通过代码逻辑来 ...

  5. ecshop笔记

    ***ecshop在线入门手册***:http://book.ecmoban.com/ 解决ecshop与jquery冲突问题1.修改文件:/js/transport.js在文件最底部增加代码: if ...

  6. ch12 GUI

    <Head First Java 2nd Edition> 摘录 JFrame 代表屏幕上的一个窗口,可以把 buttons, checkboxes, test fields 等等界面相关 ...

  7. 18年多校-1002 Balanced Sequence

    >>点击进入原题测试<< 思路:自己写没写出来,想不通该怎么排序好,看了杜神代码后补题A掉的.重新理解了一下优先队列中重载小于号的含义,这里记录一下这种排序方式. #inclu ...

  8. 使用 XMLHttpRequest实现Ajax

    [XMLHttpRequest的概述] 1.XMLHttpRequest最早是在IE5中以ActiveX组件的形式实现的.非W3C标准 2.创建XMLHttpRequest对象(由于非标准所以实现方法 ...

  9. Java基础学习总结(78)——Java main方法深入研究学习

    1.不用main方法如何定义一个类? 不行,没有main方法我们不能运行Java类. 在Java 7之前,你可以通过使用静态初始化运行Java类.但是,从Java 7开始就行不通了. 2.main() ...

  10. C++中const引用的是对象的时候只能调用该对象的f()const方法

    const引用的作用: 1. 避免不必要的复制.  2. 限制不能修改对象. const 引用的是对象时只能访问该对象的const 函数  例: class A { public: void cons ...