【 bzoj4537】HNOI2016 最小公倍数
首先将边按a的值分组,每$\sqrt{m}$一组。
对于每一组,将符合一组a的询问选出来,将这些询问和这一块之前的边(a一定小于这些询问)按b排序,然后交替插入,询问,对于一个询问,在当前块也有可能有满足的边,我们将其加入,考虑后并撤销,由于块大小是$\sqrt{m}$所以复杂度正确。
注意 : 1.并查集不能路径压缩,否则无法撤销;
2.在筛选一组的询问时,不要让一个询问被考虑多次,也就是说用询问的a小于终点后的那条边的a作为筛选条件,否则假如所有的a一样,那么每个询问每次都会被考虑一遍。
复杂度为$\sqrt{m}mlog(m) + Q \sqrt{m}$
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define drep(i, a, b) for (int i = a; i >= b; i--)
#define REP(i, a, b) for (int i = a; i < b; i++)
#define pb push_back
#define mp make_pair
#define xx first
#define yy second
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
template <typename T> void Max(T& a, T b) { if (b > a) a = b; }
//********************************* const int maxn = , maxm = ;
struct DATA {
int u, v, a, b, id;
} e[maxm], q[maxn], tmp[maxn];
bool cmpa(DATA a, DATA b) { return a.a < b.a; }
bool cmpb(DATA a, DATA b) { return a.b < b.b; } struct Option {
int x, y, xmaxa, xmaxb, sz, ymaxa, ymaxb, f; Option() {}
Option(int _x, int _y, int _xmaxa, int _xmaxb, int _sz, int _ymaxa, int _ymaxb, int _f) :
x(_x), y(_y), xmaxa(_xmaxa), xmaxb(_xmaxb), sz(_sz), ymaxa(_ymaxa), ymaxb(_ymaxb), f(_f) {}
} op[maxn]; int top;
int fa[maxn], sz[maxn], maxa[maxn], maxb[maxn];
int ans[maxn];
int getfather(int x) { return fa[x] == x ? x : getfather(fa[x]); }
void merge(int x, int y, int a, int b) {
int fx = getfather(x), fy = getfather(y);
if (sz[fx] < sz[fy]) swap(fx, fy);
op[++top] = (Option){fx, fy, maxa[fx], maxb[fx], sz[fx], maxa[fy], maxb[fy], fa[fy]};
if (fx == fy) {
maxa[fx] = max(maxa[fx], a);
maxb[fx] = max(maxb[fx], b);
return;
}
sz[fx] += sz[fy];
maxa[fx] = max(maxa[fx], max(maxa[fy], a));
maxb[fx] = max(maxb[fx], max(maxb[fy], b));
fa[fy] = fx;
} void retrace() {
drep(i, top, ) {
maxa[op[i].x] = op[i].xmaxa;
maxb[op[i].x] = op[i].xmaxb;
maxa[op[i].y] = op[i].ymaxa;
maxb[op[i].y] = op[i].ymaxb;
fa[op[i].y] = op[i].f;
sz[op[i].x] = op[i].sz;
}
} int main() {
/*
freopen("multiple.in", "r", stdin);
freopen("multiple.out", "w", stdout);
*/
int n, m; scanf("%d%d", &n, &m);
rep(i, , m) scanf("%d%d%d%d", &e[i].u, &e[i].v, &e[i].a, &e[i].b);
int Q; scanf("%d", &Q);
rep(i, , Q) scanf("%d%d%d%d", &q[i].u, &q[i].v, &q[i].a, &q[i].b), q[i].id = i;
int Sz = sqrt(m); sort(e + , e + + m, cmpa);
sort(q + , q + + Q, cmpb); for (int st = ; st <= m; st += Sz) {
int end = min(st + Sz - , m); int cnt();
for (int i = ; i <= Q; i++) if (q[i].a >= e[st].a && (st + Sz > m || q[i].a < e[end + ].a)) tmp[++cnt] = q[i];
if (!cnt) continue; sort(e + , e + st, cmpb); rep(i, , n) fa[i] = i, sz[i] = , maxa[i] = maxb[i] = -;
for (int k = , j = ; k <= cnt; k++) {
while (e[j].b <= tmp[k].b && j < st) merge(e[j].u, e[j].v, e[j].a, e[j].b), j++; top = ;
rep(i, st, end) if (e[i].a <= tmp[k].a && e[i].b <= tmp[k].b) merge(e[i].u, e[i].v, e[i].a, e[i].b);
int fx = getfather(tmp[k].u), fy = getfather(tmp[k].v);
if (fa[fx] == fa[fy] && maxa[fx] == tmp[k].a && maxb[fx] == tmp[k].b) ans[tmp[k].id] = ;
retrace();
} }
rep(i, , Q) if (ans[i]) puts("Yes"); else puts("No"); return ;
}
multiple
【 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]最小公倍数
将边按$a$从小到大排序,每$\sqrt{m}$个取一个关键点. 对于每个关键点,将这个点之前的边以及要在这个关键点回答的询问按$b$排序. 依次加入这个关键点之前的每条边,用并查集维护每个连通块$a ...
- 【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} ...
- 4537: [Hnoi2016]最小公倍数
Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你 ...
随机推荐
- xcconfig 文件配置文件 问题
与公司 QA 聊天,已不止一次被吐槽说移动端从开发环境转到生产环境时,还要靠修改代码来配置对应的环境参数.她认为,从 App 转测试之后,就不应该再修改代码,可以把所有的环境配置都整合到配置文件中,这 ...
- Loadrunner性能测试分类详(二)
一.基准测试 有基础的标准,这样能通过对比发现系统的不同点与变化. 1.可以再指定的标准下通过基准测试建立一个性能基准,这样以后当系统的环境.参数发生变化后,再进行一次相同标准下的测试,即可看出变化对 ...
- HDU1102--Constructing Roads(最小生成树)
Problem Description There are N villages, which are numbered from 1 to N, and you should build some ...
- jsp导入外部样式
在博客园遇到一位朋友,她将我的代码下载下去,运行的时候,jsp页面的样式不存在,不会显示出来. 这里就将我之前写的SpringSpringmvcMybatis做一些修改. jdk1.8 加入了两个ja ...
- Mybatis学习(5)高级映射
需求: 一.一对一查询 查询订单信息,关联查询创建订单的用户信息: orders--->user:一个订单只由一个用户创建,一对一 orders表 和 user表: 1)使用resultType ...
- SVM阅读资料
1,Andrew Ng机器学习公开课笔记 -- 支持向量机 2,http://blog.pluskid.org/?page_id=683 3,支持向量机SVM(一) 4,机器学习中的算法(2)-支持向 ...
- 以前的loginUI
的 <%@ page language="java" pageEncoding="UTF-8"%> <%@ include file=&quo ...
- 基础DP的一些知识总结(未完成)
DP的思路: ①DAG上的最长(短)路问题 有两种状态转移, 第一个就是从其他状态获得状态F[i],第二个就是从F[i]得到其他独立的状态,这里一定要是独立的,不然后面更新的时候会遗漏.这两种状态各有 ...
- Ubuntu安装完后设置root密码
安装完Ubuntu 14.04后默认是没有主动设置root密码的,也就无法进入根用户. 相关阅读: Ubuntu 14.04 下载.安装.配置 整理汇总 页面 http://www.linuxidc. ...
- Eclipse的Java工作集和多工程构建路径
一.Java工作集: Eclipse有一个小功能,就是创建Java Working Set.它的作用是解决Package Explorer窗格中创建很多工程时出现拥挤的麻烦. 在创建(New对话框)时 ...