Description

  给定一张 NNN 个顶点 M" role="presentation" style="position: relative;">MMM 条边的无向图(顶点编号为 1,2,…,n1,2,…,n1,2,…,n ),每条边上带有权值。所有权值都可以分解成 2a×3b2a×3b2^a\times3^b 的形式。现在有 qqq 个询问,每次询问给定四个参数 u" role="presentation" style="position: relative;">uuu 、 vvv 、 a" role="presentation" style="position: relative;">aaa 和 bbb ,请你求出是否存在一条顶点 u" role="presentation" style="position: relative;">uuu 到 vvv 之间的路径,使得路径依次经过的边上的权值的最小公倍数为 2a×3b" role="presentation" style="position: relative;">2a×3b2a×3b2^a\times3^b 。注意:路径可以不是简单路径。
  下面是一些可能有用的定义:
  最小公倍数: KKK 个数 a1,a2,…,ak" role="presentation" style="position: relative;">a1,a2,…,aka1,a2,…,aka_1,a_2,…,a_k 的最小公倍数是能被每个 aiaia_i 整除的最小正整数。
  路径:路径 P:P1,P2,…,PkP:P1,P2,…,PkP:P_1,P_2,…,P_k 是顶点序列,满足对于任意 1≤i<k1≤i<k1\le i ,节点 PiPiP_i 和 Pi+1Pi+1P_{i+1} 之间都有边相连。
简单路径:如果路径 P:P1,P2,…,PkP:P1,P2,…,PkP:P_1,P_2,…,P_k 中,对于任意 1≤s≠t≤k1≤s≠t≤k1\le s\ne t\le k 都有 Ps≠PtPs≠PtP_s\ne P_t,那么称路径为简单路径。

Input

  输入文件的第一行包含两个整数 NNN 和 M" role="presentation" style="position: relative;">MMM ,分别代表图的顶点数和边数。接下来 MMM 行,每行包含四个整数 u" role="presentation" style="position: relative;">uuu 、 vvv 、 a" role="presentation" style="position: relative;">aaa 、 bbb 代表一条顶点 u" role="presentation" style="position: relative;">uuu 和 vvv 之间、权值为 2a×3b" role="presentation" style="position: relative;">2a×3b2a×3b2^a\times3^b 的边。接下来一行包含一个整数 qqq ,代表询问数。接下来 q" role="presentation" style="position: relative;">qqq 行,每行包含四个整数 uuu 、 v" role="presentation" style="position: relative;">vvv 、 aaa 和 b" role="presentation" style="position: relative;">bbb ,代表一次询问。询问内容请参见问题描述。
  1≤n,q≤50000,1≤m≤100000,0≤a,b≤1091≤n,q≤50000,1≤m≤100000,0≤a,b≤1091\le n,q\le50000,1\le m\le100000,0\le a,b\le10^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

Solution

题意就是一个图,每条边上有 222 个权值 a,b" role="presentation" style="position: relative;">a,ba,ba,b ,每次询问是否有一条 uuu 到 v" role="presentation" style="position: relative;">vvv 的路径(不一定是简单路径),使得路径上的 aaa 的最大值和 b" role="presentation" style="position: relative;">bbb 的最大值恰好等于一个给定的值。
考虑一个暴力的 O((n+m)q)O((n+m)q)O((n+m)q) 算法:
维护一个带权并查集,维护每个连通块的 aaa 最大值和 b" role="presentation" style="position: relative;">bbb 最大值。
对于一个询问 (u,v,A,B)(u,v,A,B)(u,v,A,B) ,初始化并查集,并将所有满足 a≤A,b≤Ba≤A,b≤Ba\le A,b\le B 的边加入,最后询问 uuu 和 v" role="presentation" style="position: relative;">vvv 是否连通,以及连通块的最大值是否为 A,BA,BA,B 。
考虑使用分块优化。
先将所有的边按照 aaa 从小到大排序,分成 m" role="presentation" style="position: relative;">m−−√m\sqrt m 块,然后在每一块内按照 bbb 排序。
那么对于一个询问,满足条件的边一定是这样分布的(红色部分):

即合法的边分布在前 k" role="presentation" style="position: relative;">kkk 块,前 k−1k−1k-1 块中合法的边在块内是一个前缀,在第 kkk 块中是零散的。
因此,可以把询问按照 k" role="presentation" style="position: relative;">kkk 进行分组,对每组询问分类处理。
假设现在处理到第 kkk 组询问,则将询问按照 B" role="presentation" style="position: relative;">BBB 从小到大排序。
按照 BBB 从小到大排序之后,对于前 k−1" role="presentation" style="position: relative;">k−1k−1k-1 块中选出的边,选到的右边界是递增的,因此用 k−1k−1k-1 个指针维护前 k−1k−1k-1 块取到的右边界即可。
第 kkk 块是零散的,暴力加边。但由于不同询问中第 k" role="presentation" style="position: relative;">kkk 块内选出的边不同,因此要写一个可持久化支持撤回上一次操作的并查集。

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i, a, b) for (i = a; i <= b; i++)
using namespace std;
inline int read() {int res = 0; bool bo = 0; char c;while (((c = getchar()) < '0' || c > '9') && c != '-');if (c == '-') bo = 1; else res = c - 48;while ((c = getchar()) >= '0' && c <= '9')res = (res << 3) + (res << 1) + (c - 48);return bo ? ~res + 1 : res;
}
const int N = 5e4 + 5, M = 1e5 + 5, L = 1e6 + 5, Sqrt = 1005;
int n, m, q, S, fa[N], max2[N], max3[N], QAQ, QWQ, l[Sqrt], r[Sqrt], cnt,
pos[Sqrt], tot, que[M], mina[Sqrt];
bool vis[M], ans[M];
struct cyx {int t, u, f, u2, u3, f2, f3;} o[L];
struct pyz {int u, v, a, b, id;} e[M], c[M];
inline bool comp1(const pyz &x, const pyz &y) {return x.a < y.a;}
inline bool comp2(const pyz &x, const pyz &y) {return x.b < y.b;}
inline int cx(const int &x, const bool &op) {if (!op) {int y = x; while (fa[y] != y) y = fa[y]; return y;}if (fa[x] != x) o[++QAQ] = (cyx) {QWQ, x, fa[x], -2, -2, -2, -2}, fa[x] = cx(fa[x], 1); return fa[x];
}
inline void zm(const int &x, const int &y, const int &a, const int &b) {QWQ++; int ix = cx(x, 1), iy = cx(y, 1);if (ix != iy) o[++QAQ] = (cyx) {QWQ, iy, ix, max2[iy], max3[iy],max2[ix], max3[ix]}, fa[iy] = ix, max2[ix] =max(max(max2[ix], max2[iy]), a), max3[ix] = max(max(max3[ix],max3[iy]), b), max2[iy] = max3[iy] = -1;else o[++QAQ] = (cyx) {QWQ, ix, -2, max2[ix], max3[ix], -2, -2},max2[ix] = max(max2[ix], a), max3[ix] = max(max3[ix], b);
}
inline void backto(const int &t) {while (o[QAQ].t > t) {if (o[QAQ].f == -2) max2[o[QAQ].u] = o[QAQ].u2,max3[o[QAQ].u] = o[QAQ].u3;else {fa[o[QAQ].u] = o[QAQ].u2 == -2 ? o[QAQ].f : o[QAQ].u;if (o[QAQ].u2 != -2) {max2[o[QAQ].u] = o[QAQ].u2; max3[o[QAQ].u] = o[QAQ].u3;max2[o[QAQ].f] = o[QAQ].f2; max3[o[QAQ].f] = o[QAQ].f3;}}QAQ--;}QWQ = t;
}
int main() {int i, j, k; n = read(); m = read();For (i, 1, m) e[i].u = read(), e[i].v = read(),e[i].a = read(), e[i].b = read();q = read(); For (i, 1, q) c[i].u = read(), c[i].v = read(),c[i].a = read(), c[i].b = read(), c[i].id = i; S = sqrt(m);sort(e + 1, e + m + 1, comp1);for (i = 1; i <= m; i += S) l[++cnt] = i, r[cnt] = min(m, i + S - 1),mina[cnt] = e[l[cnt]].a; For (i, 1, cnt)sort(e + l[i], e + r[i] + 1, comp2); sort(c + 1, c + q + 1, comp2);For (i, 1, cnt) {For (j, 1, n) fa[j] = j, max2[j] = max3[j] = -1; QAQ = QWQ = tot = 0;For (j, 1, i - 1) pos[j] = l[j]; For (j, 1, q)if (!vis[j] && (i == cnt || mina[i + 1] > c[j].a))vis[que[++tot] = j] = 1;For (j, 1, tot) {For (k, 1, i - 1) while (pos[k] <= r[k] && e[pos[k]].b <= c[que[j]].b)zm(e[pos[k]].u, e[pos[k]].v, e[pos[k]].a, e[pos[k]].b), pos[k]++;int tmp = QWQ; For (k, l[i], r[i])if (e[k].a <= c[que[j]].a && e[k].b <= c[que[j]].b)zm(e[k].u, e[k].v, e[k].a, e[k].b);int x = cx(c[que[j]].u, 0), y = cx(c[que[j]].v, 0);ans[c[que[j]].id] = x == y && max2[x] == c[que[j]].a&& max3[y] == c[que[j]].b; backto(tmp);}}For (i, 1, q) puts(ans[i] ? "Yes" : "No");return 0;
}

[BZOJ4537][Hnoi2016]最小公倍数(并查集+分块)相关推荐

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

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

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

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

  3. CF896E Welcome home, Chtholly(分块/并查集/第二分块)

    CF896E Welcome home, Chtholly 对于给定一个长度为n(n<=1e5)的序列,值域范围为1e5,要求支持两类操作. 将区间[l,r]内所有大于x的数减x 查询区间[l, ...

  4. CF896E Welcome home,Chtholly/[Ynoi2018]五彩斑斓的世界(并查集+第二分块)

    CF896E Welcome home,Chtholly/[Ynoi2018]五彩斑斓的世界 description solution code description 五彩斑斓的世界 CF896E ...

  5. [HNOI2016]最小公倍数

    题面 \(\text{Solution:}\) 显然在线算法根本不可做,先将询问离线,按 \(b\) 排序. 注意到不一定是简单路径,所以一个询问回答为 \(Yes\) 当且仅当 \(u,v\) 在同 ...

  6. HDU - 2874 Connections between cities(并查集+LCA)

    题目链接:点击查看 题目大意:给出n个点代表城市,再给出m条边将其连接,每条边都有边权,题目保证给出的图无环,现在给出两个点,首先询问两个点是否互相连通,若可以连通,询问两点之间的距离 题目分析:判断 ...

  7. 2017百度之星程序设计大赛 - 资格赛【1001 Floyd求最小环 1002 歪解(并查集),1003 完全背包 1004 01背包 1005 打表找规律+卡特兰数】...

    度度熊保护村庄 Accepts: 13 Submissions: 488 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3276 ...

  8. 并查集(Union-Find)

    并查集(Union-Find) 并查集(Union-Find) 1.初始化 2.查询 3.合并 4.平衡性优化,扁平化 5.按秩合并 6.路径压缩 7.代码 常用模板 [★ 547. 省份数量](ht ...

  9. 数据结构课--并查集(标号法)

    小谈并查集 并查集是什么: "并"和"查"是两个功能:"集"表示集合 解决一种把大量数据分块后查找某些数据是否是同一类的问题. 一般由fin ...

最新文章

  1. java es 5.0.1_es.5.1.1启动失败
  2. Java 7 并发编程指南
  3. python canvas获取的图片流数据为空
  4. boost::ptr_vector相关的测试程序
  5. (010) Linux之I/O重定向
  6. matlab kfda,SVD与KFDA相结合人脸识别-matlab-毕业论文
  7. NET分页实现及代码
  8. 浅谈tcpwrapper的基本使用方法
  9. 图卷积网络GCN理解
  10. 基于LED的室内可见光通信系统
  11. 剪贴板查看器clipbrd.exe
  12. 使用liteide开发go问题收集
  13. 延迟队列DelayQueue研究
  14. IP地址和 MAC地址详解
  15. 苹果mac笔记本部分按键失灵,为什么要5连按⌥ option键
  16. 有趣且重要的Git知识合集(5)Merge branch ‘master‘ of
  17. 你不是迷茫,你只是浮躁
  18. java英文字母_用JAVA编一个程序输出全部的英文字母
  19. [solved] login to server failed: EOF
  20. 按键精灵加密html,按键精灵HtmlCheck 选择/清除网页中的单选框或复选框 | 学步园...

热门文章

  1. REVIT 卸载工具,完美彻底卸载清除干净revit各种残留注册表和文件
  2. vue调用高德地图实现定位
  3. esp32邮件服务器,ESP32智能家居集线器的制作
  4. boost::asio::tcp
  5. 【C标准库1】math.h
  6. 【3.3 ads篇(重点)】
  7. 爬取天气时常用的城市代码(备忘)
  8. Python学习笔记(一)——Anaconda安装与配置(windows)
  9. 【Java】- Incompatible types. Found: java. lang. String', required:' byte, char, short or int'
  10. 我迄今见过最完美的中文编程开发工具