[HNOI2016]最小公倍数
题目描述
给定一张N个顶点M条边的无向图(顶点编号为1,2,...,n),每条边上带有权值。所有权值都可以分解成2a∗3b2^a*3^b2a∗3b 的形式。
现在有q个询问,每次询问给定四个参数u、v、a和b,请你求出是否存在一条顶点u到v之间的路径,使得路径依次经过的边上的权值的最小公倍数为2a∗3b2^a*3^b2a∗3b 。
注意:路径可以不是简单路径。下面是一些可能有用的定义:最小公倍数:K个数a1,a2,...,ak的最小公倍数是能被每个ai整除的最小正整数。
路径:路径P:P1,P2,...,Pk是顶点序列,满足对于任意1<=i<k,节点Pi和Pi+1之间都有边相连。简单路径:如果路径P:P1,P2,...,Pk中,对于任意1≤s≠t≤k1\le s\ne t\le k1≤s≠t≤k 都有Ps≠PtPs\ne PtPs≠Pt ,那么称路径为简单路径。
输入输出格式
输入格式:
输入文件的第一行包含两个整数N和M,分别代表图的顶点数和边数。接下来M行,每行包含四个整数u、v、a、b代表一条顶点u和v之间、权值为2a∗3b2^a*3^b2a∗3b 的边。接下来一行包含一个整数q,代表询问数。接下来q行,每行包含四个整数u、v、a和b,代表一次询问。询问内容请参见问题描述。1<=n,q<=50000、1<=m<=100000、0<=a,b<=10^9
输出格式:
对于每次询问,如果存在满足条件的路径,则输出一行Yes,否则输出一行 No(注意:第一个字母大写,其余字母小写) 。
输入输出样例
Yes
Yes
Yes
No
No
对于每个询问,我们可以把所有(a,b)小于等于的边加入并查集
并查集维护联通块的最大a和最大b,分别为Maxa,Maxb
如果最大(Maxa,Maxb)=(a,b)
暴力显然不行
现将边按a排序,分块
将询问按b排序
每一块加入a值在这一块的范围内的询问,即大于等于a[i]小于a[i+√m]
前面的块里的边显然a值都符合需求,按b排序
从前往后枚举加入的询问,将前面块里小于b的边加入
因为满足当前询问的边,必定也满足下一个询问,所以不需要撤销
然后枚举当前块里的边加入,处理完当前询问要撤销并查集的操作
因为撤销操作需要储存状态并复原,只有根号个撤销操作,复杂度有保证
不能用路径压缩
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct Node
{
int u,v,a,b,id;
}e[],q[],pre[],p[];
int set[],tot,Maxa[],Maxb[],n,m,lim,r,cnt,ans[],size[];
int gi()
{
char ch=getchar();
int x=;
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='')
{
x=(x<<)+(x<<)+ch-'';
ch=getchar();
}
return x;
}
bool cmpa(Node x,Node y)
{
if (x.a==y.a) return x.b<y.b;
return x.a<y.a;
}
bool cmpb(Node x,Node y)
{
if (x.b==y.b) return x.a<y.a;
return x.b<y.b;
}
int find(int x)
{
if (set[x]==x) return x;
if (set[x]!=x) return find(set[x]);
}
void merge(Node E)
{
int p=find(E.u),q=find(E.v);
if (size[p]<size[q]) swap(p,q);
++tot;
pre[tot].u=p,pre[tot].v=q,pre[tot].a=Maxa[p],pre[tot].b=Maxb[p];pre[tot].id=size[p];
if (p!=q)
{
set[q]=p;
size[p]+=size[q];
}
if (Maxa[p]<E.a)
Maxa[p]=E.a;
if (Maxa[p]<Maxa[q])
Maxa[p]=Maxa[q];
if (Maxb[p]<E.b)
Maxb[p]=E.b;
if (Maxb[p]<Maxb[q])
Maxb[p]=Maxb[q];
}
void undo()
{int i;
Node E;
for (;tot;tot--)
{
E=pre[tot];
set[E.v]=E.v;
Maxa[E.u]=E.a;
Maxb[E.u]=E.b;
size[E.u]=E.id;
}
}
int main()
{int i,j,k,l,ed,p1,p2;
cin>>n>>m;
lim=sqrt(m);
for (i=;i<=m;i++)
{
e[i].u=gi();e[i].v=gi();e[i].a=gi();e[i].b=gi();
e[i].id=i;
}
cin>>r;
for (i=;i<=r;i++)
{
q[i].u=gi();q[i].v=gi();q[i].a=gi();q[i].b=gi();
q[i].id=i;
}
sort(e+,e+m+,cmpa);
sort(q+,q+r+,cmpb);
for (i=;i<=m;i+=lim)
{
cnt=;tot=;
k=;
for (j=;j<=r;j++)
if (q[j].a>=e[i].a&&(i+lim>m||q[j].a<e[i+lim].a))
p[++cnt]=q[j];
if (cnt==0) continue;
sort(e+,e+i,cmpb);
if (i+lim-<=m) ed=i+lim-;
else ed=m;
for (j=;j<=n;j++)
set[j]=j,Maxa[j]=-,Maxb[j]=-,size[j]=;
for (j=;j<=cnt;j++)
{
for (;k<i;k++)
if (p[j].b>=e[k].b) merge(e[k]);
else break;
tot=;
for (l=i;l<=ed;l++)
if (p[j].b>=e[l].b&&p[j].a>=e[l].a)
{
merge(e[l]);
}
else if (e[l].a>p[j].a) break;
p1=find(p[j].u),p2=find(p[j].v);
if (p1==p2&&Maxa[p1]==p[j].a&&Maxb[p1]==p[j].b)
ans[p[j].id]=;
undo();
}
}
for (i=;i<=r;i++)
if (ans[i])
puts("Yes");
else puts("No");
}
[HNOI2016]最小公倍数的更多相关文章
- 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]最小公倍数(分块+并查集)
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]最小公倍数 分块
[BZOJ4537][Hnoi2016]最小公倍数 Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在 ...
- 4537: [Hnoi2016]最小公倍数
Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你 ...
- bzoj 4537 HNOI2016 最小公倍数
Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,-,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你 ...
- 洛谷P3247 [HNOI2016]最小公倍数 [分块,并查集]
洛谷 思路 显然,为了达到这个最小公倍数,只能走\(a,b\)不是很大的边. 即,当前询问的是\(A,B\),那么我们只能走\(a\leq A,b\leq B\)的边. 然而,为了达到这最小公倍数,又 ...
- [HNOI2016]最小公倍数 (可回退并查集,回滚莫队)
题面 题目链接 题目描述 给定一张 N N N 个顶点 M M M 条边的无向图(顶点编号为 1 , 2 , - , n 1,2,\ldots,n 1,2,-,n),每条边上带有权值.所有权值都可以分 ...
随机推荐
- Alpha冲刺——Day1
一.合照 二.项目燃尽图 三.项目进展 1.界面设计:图形界面部分完成 2.数据库设计:数据库设计基本完成 3.搭建基本服务器框架 github链接 四.明日规划 1.继续完成剩下的图形界面 2.An ...
- 测试与发布(Beta版本)
评分基准: 按时交 - 有分(测试报告-10分,发布说明-10分,展示博客-10分),检查的项目包括后文的两个方面 测试报告(基本完成5分,根据完成质量加分,原则上不超过满分10分) 发布说明(基本完 ...
- C程序设计-----第0次作业
C程序设计-----第0次作业- 1.翻阅邹欣老师的关于师生关系博客,并回答下列问题,每个问题的答案不少于500字:(50分)- 1)最理想的师生关系是健身教练和学员的关系,在这种师生关系中你期望获得 ...
- scrapy 博客爬取
item.py import scrapy class FulongpjtItem(scrapy.Item): # define the fields for your item here like: ...
- Linux之用户与用户组
1.Linux是一种 多用户多任务分时操作系统. 2.Linux的用户只有两个等级:root用户和非root用户. Linux系统默认 内置了root用户 和一些非root用户,如nobody,a ...
- Hibernate之深入持久化对象
Hibernate是一个彻底的O/R Mapping 框架.之所以说彻底,是因为相对于其他的 框架 ,如Spring JDBC,iBatis 需要手动的管理SQL语句,Hibernate采用了完全 面 ...
- 从一次输入框无法输入的bug,谈如何限制输入框输入类型
bug的产生和修改 上周临近周末休息的时候,一个同事跑过来了,对我说:"阿伦啊,有一个页面出问题了,火狐浏览器所有的input都没法输入了."我一听,是不是你给加了什么属性,让in ...
- Winserver+Apache+django部署
废话不多说,干活直接上. winserver2012 + django2.0.1 + apache 部署过程 python ==> 3.4 64位 https://www.python.org/ ...
- mongodb监控工具mongostat
mongostat的使用及命令详解 mongostat是mongodb自带的状态检测工具,在命令行下使用,会间隔固定时间获取mongodb的当前运行状态,并输出. 1.常用命令格式: mongosta ...
- c# windows service 实现监控其他程序是否被关闭,关闭则报警
namespace MonitorService { public partial class MonitorSv : ServiceBase { string AppName = "&qu ...