Description

题库链接

给定一张 \(N\) 个顶点 \(M\) 条边的无向图(顶点编号为 \(1,2,\cdots,n\) ),每条边上带有权值。所有权值都可以分解成 \(2^a\times 3^b\) 的形式。 \(q\) 个询问,每次询问给定四个参数 \(u,v,a,b\) ,请你求出是否存在一条顶点 \(u\) 到 \(v\) 之间的路径,使得路径依次经过的边上的权值的最小公倍数为 \(2^a\times 3^b\) 。

\(1\leq n,q\leq 50000,1\leq m\leq 100000\)

Solution

容易发现题中要求的就是找一条可以是非简单路径的路径连接 \(u,v\) 并且边权 \(a'\) 最大值为 \(a\) ,边权 \(b'\) 最大值为 \(b\) 。

考虑暴力就是对于每组询问,将边的 \(a\) 值小于等于询问的 \(a\) 值且 \(b\) 值小于等于询问的 \(b\) 值的边加入图中。判断 \(u,v\) 是否联通,且联通块内 \(a_{max},b_{max}\) 是否与询问的值相等。

显然这样的复杂度是假的。优化暴力,考虑分块。

边按 \(a\) 排序,然后分块。对于每一块 \(i\) ,处理 \(a'\) 在这一块中的询问。这时候之前块的 \(a<a'\) 这一个关系一定满足,按 \(b\) 排序后也满足 \(b<b'\) 了。

块 \(i\) 中还有一些满足的,最多 \(\sqrt m\) 。

暴力加入然后撤销就可以了。不路径压缩的并查集,按秩合并的话复杂度 \(log_2 n\) 。

总复杂度 \(O(m\sqrt m log_2 n)\) 。

Code

//It is made by Awson on 2018.3.3
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 50000, M = 100000;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); } int n, m, q, lim, ans[N+5];
struct tt {int u, v, a, b, id; }edge[M+5], query[N+5], tmp[N+5], pre[N+5];
bool comp1(const tt &a, const tt &b) {return a.a == b.a ? a.b < b.b : a.a < b.a; }
bool comp2(const tt &a, const tt &b) {return a.b == b.b ? a.a < b.a : a.b < b.b; }
struct Set {
int fa[N+5], ma[N+5], mb[N+5], rank[N+5], pos;
void clear() {for (int i = 1; i <= n; i++) fa[i] = rank[i] = 0, ma[i] = mb[i] = -1; }
int find(int u) {return fa[u] ? find(fa[u]) : u; }
void merge(int u, int v, int a, int b) {
u = find(u), v = find(v); if (rank[u] > rank[v]) Swap(u, v);
ma[v] = max(ma[v], max(ma[u], a)), mb[v] = max(mb[v], max(mb[u], b));
if (u != v) fa[u] = v, rank[v] += (rank[v] == rank[u]);
}
void unin(int u, int v, int a, int b) {
u = find(u), v = find(v); if (rank[u] > rank[v]) Swap(u, v); ++pos;
pre[pos].u = u, pre[pos].v = v, pre[pos].a = ma[v], pre[pos].b = mb[v], pre[pos].id = rank[v];
ma[v] = max(ma[v], max(ma[u], a)), mb[v] = max(mb[v], max(mb[u], b));
if (u != v) fa[u] = v, rank[v] += (rank[v] == rank[u]);
}
void undo() {
while (pos) {
int u = pre[pos].u, v = pre[pos].v, a = pre[pos].a, b = pre[pos].b, rk = pre[pos].id;
if (u != v) fa[u] = 0, rank[v] = rk;
ma[v] = a, mb[v] = b; --pos;
}
}
}T; void work() {
read(n), read(m); lim = sqrt(m);
for (int i = 1; i <= m; i++) read(edge[i].u), read(edge[i].v), read(edge[i].a), read(edge[i].b);
read(q);
for (int i = 1; i <= q; i++) read(query[i].u), read(query[i].v), read(query[i].a), read(query[i].b), query[i].id = i;
sort(edge+1, edge+1+m, comp1); sort(query+1, query+1+q, comp2);
for (int i = 1; i <= m; i = i+lim) {
int cnt = 0, k = 1, ed = Min(i+lim-1, m);
for (int j = 1; j <= q; j++) if (query[j].a >= edge[i].a && (i+lim > m || query[j].a < edge[i+lim].a)) tmp[++cnt] = query[j];
sort(edge+1, edge+i, comp2); T.clear();
for (int j = 1; j <= cnt; j++) {
while (k < i && edge[k].b <= tmp[j].b) T.merge(edge[k].u, edge[k].v, edge[k].a, edge[k].b), ++k;
for (int q = i; q <= ed; q++) if (edge[q].a <= tmp[j].a && edge[q].b <= tmp[j].b) T.unin(edge[q].u, edge[q].v, edge[q].a, edge[q].b);
int u = T.find(tmp[j].u), v = T.find(tmp[j].v);
if (u == v && T.ma[u] == tmp[j].a && T.mb[u] == tmp[j].b) ans[tmp[j].id] = 1;
T.undo();
}
}
for (int i = 1; i <= q; i++) puts(ans[i] ? "Yes" : "No");
}
int main() {
work(); return 0;
}

[HNOI 2016]最小公倍数的更多相关文章

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

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

  2. [HNOI 2016]树

    Description 题库链接 给你一棵 \(N\) 个节点根节点为 \(1\) 的有根树,结点的编号为 \(1\sim N\) :我们称这颗树为模板树.需要通过这棵模板树来构建一颗大树.构建过程如 ...

  3. 【BZOJ 4539】【HNOI 2016】树

    http://www.lydsy.com/JudgeOnline/problem.php?id=4539 今天测试唯一会做的一道题. 按题目要求,如果暴力的把模板树往大树上仍,最后得到的大树是$O(n ...

  4. hnoi 2016 省选总结

    感觉省选好难的说...反正我数据结构太垃圾正解想到了也打不出来打一打暴力就滚粗了! DAY1 0+20+30 DAY2 60-20+0+60 最后170-20分,暴力分还是没有拿全! 然而这次是给了5 ...

  5. HNOI 2016 省队集训日记

    第一天 DeepDarkFantasy 从东京出发,不久便到一处驿站,写道:日暮里.  ——鲁迅<藤野先生> 定义一个置换的平方为对1~n的序列做两次该置换得到的序列.已知一个置换的平方, ...

  6. 数据结构(树链剖分,堆):HNOI 2016 network

    2215. [HNOI2016]网络 ★★★☆   输入文件:network_tenderRun.in   输出文件:network_tenderRun.out   简单对比时间限制:2 s   内存 ...

  7. [HNOI 2016]序列

    Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) ,给出 \(q\) 组询问.每次询问 \([l,r]\) ,求该区间内所有的子序列中最小值的和. \(1\leq n, ...

  8. [HNOI 2016]大数

    Description 题库链接 给你一个长度为 \(n\) ,可含前导零的大数,以及一个质数 \(p\) . \(m\) 次询问,每次询问你一个大数的子区间 \([l,r]\) ,求出子区间中有多少 ...

  9. [HNOI 2016]网络

    Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做 一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有 ...

随机推荐

  1. java多线程的(一)-之java线程的使用

    一.摘要 每天都和电脑打交道,也相信大家使用过资源管理器杀掉过进程.而windows本身就是多进程的操作系统 在这里我们理解两组基本概念: 1.进程和线程的区别???? 2.并行与并发的区别???? ...

  2. linux特殊字符及其作用

    1.通配符    ? 匹配单个字符    * 代表所有字符     [abcd] 匹配[]里任意一个字符.4选1 [a-d]    [!abcd]  匹配不含[]里任意一个字符的字符.[^abcd] ...

  3. [福大软工] W班 评测作业对应表

  4. C语言的第0次作业

    你认为大学的学习生活.同学关系.师生关系应该是怎样? 1.我觉得大学生活应该充实而富有意义,不荒废学业,合理分配时间,让自己有一技之长,与时代接轨. 2.同学之间应该顺其自然的相处,不做作,不矫情,真 ...

  5. 算法第四版学习笔记之优先队列--Priority Queues

    软件:DrJava 参考书:算法(第四版) 章节:2.4优先队列(以下截图是算法配套视频所讲内容截图) 1:API 与初级实现 2:堆得定义 3:堆排序 4:事件驱动的仿真 优先队列最重要的操作就是删 ...

  6. Django 测试驱动开发

    第一章 1.编写functional_tests.py from selenium import webdriver browser = webdriver.Firefox() browser.get ...

  7. img加载卡顿,解决办法

    我觉得我在这个项目里遇到了太多的第一次.比如上一篇博文:在在360.UC等浏览器,img不加载原因. 当前情况是:图片加载缓慢,图片加载时出现卡顿. 上图:我缩放了图片,估计有点变形.能说明情况就行, ...

  8. HTML 字符集

    在 HTML 中,正确的字符编码是什么?   HTML5 中默认的字符编码是 UTF-8. 这并非总是如此.早期网络的字符编码是 ASCII 码.后来,从 HTML 2.0 到 HTML 4.01,I ...

  9. 《javascript设计模式与开发实践》阅读笔记(16)—— 状态模式

    状态模式 会区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变.比如电灯的开关是开还是关,在外界的表现就完全不同. 电灯例子 按照常规思路,实现一个电灯就是构造一个电灯类,然后指定一下它的 ...

  10. python之路--day10-闭包函数

    1.命名关键字参数 格式:在*后面的参数都是命名关键字参数 特点: 1.必须被传值 2.约束函数的调用者必须按照key=value的形式传值 3.约束函数的调用者必须用我们指定的key名 def au ...