4537: [Hnoi2016]最小公倍数

Time Limit: 40 Sec  Memory Limit: 512 MB
Submit: 1687  Solved: 607
[Submit][Status][Discuss]

Description

  给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值。所有权值都可以分解成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,那么称路径为简单路径。

Input

  输入文件的第一行包含两个整数N和M,分别代表图的顶点数和边数。接下来M行,每行包含四个整数u、v、a、
b代表一条顶点u和v之间、权值为2^a*3^b的边。接下来一行包含一个整数q,代表询问数。接下来q行,每行包含四
个整数u、v、a和b,代表一次询问。询问内容请参见问题描述。1<=n,q<=50000、1<=m<=100000、0<=a,b<=10^9

Output

  对于每次询问,如果存在满足条件的路径,则输出一行Yes,否则输出一行 No(注意:第一个字母大写,其余
字母小写) 。

Sample Input

4 5
1 2 1 3
1 3 1 2
1 4 2 1
2 4 3 2
3 4 2 2
5
1 4 3 3
4 2 2 3
1 3 2 2
2 3 2 2
1 3 4 4

Sample Output

Yes
Yes
Yes
No
No

HINT

Source

[Submit][Status][Discuss]

首先如果只有一个参数a,可以直接将边和询问排序然后扫一遍即可。

现在是二维偏序问题,我们就需要合理分块了。

将边按a排序,询问按b排序,考虑分块,每次找到所有第一关键字在[L,R]中的询问,那么我们将第一关键字在[1,L)的边按第二关键字排序,就可以指针扫一遍统计答案了,对于块内的问题,直接暴力合并和撤销并查集操作即可。

 #include<cmath>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=;
struct E{ int x,y,u,v,k; }a[N],b[N],c[N],h[N];
void up(int &x,int y){ if (x<y) x=y; } bool ans[N];
int n,m,cnt,tot,fa[N],sz[N],fu[N],fv[N];
bool cmpu(const E &p,const E &q){ return p.u<q.u || (p.u==q.u && p.v<q.v); }
bool cmpv(const E &p,const E &q){ return p.v<q.v || (p.v==q.v && p.u<q.u); }
int getfa(int x){ return (x==fa[x]) ? x : getfa(fa[x]); } void merge(int x,int y,int u,int v){
x=getfa(x); y=getfa(y); if (sz[x]>sz[y]) swap(x,y);
h[++tot]=(E){x,y,fu[y],fv[y],sz[y]};
if (x!=y) fa[x]=y,sz[y]+=sz[x],up(fu[y],fu[x]),up(fv[y],fv[x]);
up(fu[y],u); up(fv[y],v);
} int main(){
freopen("bzoj4537.in","r",stdin);
freopen("bzoj4537.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,,m) scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].u,&a[i].v);
sort(a+,a+m+,cmpu); scanf("%d",&cnt);
rep(i,,cnt) scanf("%d%d%d%d",&b[i].x,&b[i].y,&b[i].u,&b[i].v),b[i].k=i;
sort(b+,b+cnt+,cmpv);
int bl=sqrt(m);
for (int i=; i<=m; i+=bl){
rep(j,,n) fa[j]=j,fu[j]=fv[j]=-,sz[j]=;
int len=;
rep(j,,cnt) if (b[j].u>=a[i].u && (i+bl>m || b[j].u<a[i+bl].u)) c[++len]=b[j];
if (!len) continue;
if (i>) sort(a+,a+i,cmpv);
for (int j=,k=; j<=len; j++){
for (; k<i && a[k].v<=c[j].v; k++) merge(a[k].x,a[k].y,a[k].u,a[k].v);
tot=;
for (int l=i; l<i+bl && l<=m; l++)
if (a[l].u<=c[j].u && a[l].v<=c[j].v) merge(a[l].x,a[l].y,a[l].u,a[l].v);
int p=getfa(c[j].x),q=getfa(c[j].y);
ans[c[j].k]=(p==q && fu[p]==c[j].u && fv[p]==c[j].v);
for (; tot; tot--) p=h[tot].x,q=h[tot].y,fa[p]=p,fu[q]=h[tot].u,fv[q]=h[tot].v,sz[q]=h[tot].k;
}
}
rep(i,,cnt) puts(ans[i]?"Yes":"No");
return ;
}

[BZOJ4537][HNOI2016]最小公倍数(分块+并查集)的更多相关文章

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

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

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

    正解:分块+并查集 解题报告: 传送门! 真的好神仙昂QAQ,,,完全想不出来,,,还是太菜了QAQ 首先还是要说下,这题可以用K-D Tree乱搞过去(数据结构是个好东西昂,,,要多学学QAQ),但 ...

  3. [APIO2019] [LOJ 3145] 桥梁(分块+并查集)(有详细注释)

    [APIO2019] [LOJ 3145] 桥梁(分块+并查集)(有详细注释) 题面 略 分析 考试的时候就感觉子任务4是突破口,结果却写了个Kruskal重构树,然后一直想怎么在线用数据结构维护 实 ...

  4. P5443 [APIO2019]桥梁 [分块+并查集]

    分块+并查集,大板子,没了. 并查集不路径压缩,可撤销,然后暴力删除 这样对于每个块都是独立的,所以直接搞就行了. 然后块内修改操作搞掉,就是单独的了 // powered by c++11 // b ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. pcap的安装

    pcap,即 packet capture library 抓包库,这个抓包库给抓包系统提供了一个高层次的接口.所有网络上的数据包,甚至是那些发送给其他主机的,通过这种机制,都是可以捕获的.它也支持把 ...

  2. Java8的Lambda表达式简介

    先阐述一下JSR(Java Specification Requests)规范,即Java语言的规范提案.是向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求 ...

  3. perl HTML::LinkExtor模块(1)

    use LWP::Simple; use HTML::LinkExtor; $html = get("http://www.baidu.com"); $link = HTML::L ...

  4. 【目录】Python自动化运维

    目录:Python自动化运维笔记 Python自动化运维 - day2 - 数据类型 Python自动化运维 - day3 - 函数part1 Python自动化运维 - day4 - 函数Part2 ...

  5. mips64高精度时钟引起ktime_get时间不准,导致饿狗故障原因分析【转】

    转自:http://blog.csdn.net/chenyu105/article/details/7720162 重点关注关中断的情况.临时做了一个版本,在CPU 0上监控所有非0 CPU的时钟中断 ...

  6. python爬虫模块之调度模块

    调度模块也就是对之前所以的模块的一个调度,作为一个流水的入口. 下面的代码的获取数据部分暂时没有写,细节部分在实际开发中,要根据要求再定义,这里说的是使用方法 from savedb import D ...

  7. 使用UpdatePanel时FileUpload失效的问题

    出处:http://www.cnblogs.com/caicainiao/archive/2010/12/08/1900377.html 1.使用UpdatePanel后,FileUpload的Has ...

  8. vue 文件引入1

    直接 <script> 引入 直接下载并用 <script> 标签引入,Vue 会被注册为一个全局变量.重要提示:在开发时请用开发版本,遇到常见错误它会给出友好的警告. 开发环 ...

  9. 【Spring事务的事务属性】

    大家都知道,Spring的声明式事务是通过事务属性来定义的,而spring的事务属性包含了5个方面:传播行为,隔离级别,是否只读,事务超时,回滚规则: 传播行为 传播行为,是属于事务边界相关的属性,定 ...

  10. linux命令(22):mkdir命令

    实例1:创建一个空目录 mkdir  test 实例2:递归创建多个目录 mkdir  -p /home/test 实例3:创建权限为777的目录 mkdir -m 777 test 实例4:创建新目 ...