[BZOJ 4537][Hnoi 2016]最小公倍数
并查集+分块
看到题目可以想到暴力做法,
对于每个询问,
将所有a和b小于等于询问值的的边加入图中(用并查集),
如果询问的u和v在一个联通块中,
且该联通块的maxa和maxb均等与询问的a和b,
则答案为Yes。
显然暴力是过不了的,于是可以用分块。
将所有边按a值升序排序,分成√m 块操作,
设每块第一条边为sp,每块长度为len,
每次操作将edge[sp].a<=a<edge[sp+len].a的询问加入询问序列,
将询问序列按b升序排列。
对于边可以分成两部分:
1、当前块之前的边;
2、当前块的边;
对于第一部分的边,其a值必定小于等于当前询问序列中的a值,
所以按b升序排序后只要边的b值小于等于询问的b值就可以加进图中,
这一部分的边加入后在处理下一个分块的询问之前都不用删(因为询问和边按b升序排序了);
对于第二部分的边,暴力加上暴力删就可以了。
至于如何暴力,开个栈把操作都记录下来就可以了。
代码:
#include<cstdio>
#include<algorithm> using namespace std; #define N ((1<<16)-1)
#define M ((1<<17)-1)
#define Q ((1<<16)-1) int n,m,ep[M],qp[Q],ans[Q],q; struct E{
int u,v,a,b;
inline void read(){scanf("%d%d%d%d",&u,&v,&a,&b);}
}e[M],que[Q]; struct ACT_stack{
int *pos[N],val[N],top;
inline void push(int*p){pos[top]=p;val[top]=*p;top++;}
inline void clear(){while (top) *pos[--top]=val[top];}
}act; struct Union_Find_sets{
int fa[N],dep[N],va[N],vb[N];
int root(int x){return fa[x]==x?x:root(fa[x]);}
inline void initialize(){for (int i=;i<=n;i++)fa[i]=i,dep[i]=,va[i]=-,vb[i]=-;}
inline void merge(E&e,bool yes)
{
int x=root(e.u),y=root(e.v),tmp;
if (x!=y)
{
if (dep[x]==dep[y])
{
if (yes) act.push(&dep[x]);
dep[x]++;
}
if (dep[x]<dep[y]) swap(x,y);
if (yes) act.push(&fa[y]);
fa[y]=x;
}
tmp=max(va[y],e.a);
if (tmp>va[x])
{
if (yes) act.push(&va[x]);
va[x]=tmp;
}
tmp=max(vb[y],e.b);
if (tmp>vb[x])
{
if (yes) act.push(&vb[x]);
vb[x]=tmp;
}
}
}ufs; void putin()
{
int i;
scanf("%d%d",&n,&m);
for (i=;i<m;i++) {e[i].read();ep[i]=i;}
scanf("%d",&q);
for (i=;i<q;i++) que[i].read();
} inline bool cmp1(const E&a,const E&b){return a.a<b.a;}
inline bool cmp2(int a,int b){return e[a].b<e[b].b;}
inline bool cmp3(int a,int b){return que[a].b<que[b].b;} void answer()
{
int sp,i,j,ne,cnt,len=,x,y;
sort(e,e+m,cmp1);
while (len*len<m)len++;
for (sp=;sp<m;sp+=len)
{
cnt=;
for (i=;i<q;i++)
if (que[i].a>=e[sp].a&&(sp+len>=m||que[i].a<e[sp+len].a)) {qp[cnt++]=i;}
if (!cnt) continue;
sort(ep,ep+sp,cmp2);
sort(qp,qp+cnt,cmp3);
ufs.initialize();
for (i=ne=;i<cnt;i++)
{
while (ne<sp&&e[ep[ne]].b<=que[qp[i]].b)
ufs.merge(e[ep[ne++]],);
for (j=sp;j<min(sp+len,m);j++)
if (e[j].a<=que[qp[i]].a&&e[j].b<=que[qp[i]].b)
ufs.merge(e[j],);
x=ufs.root(que[qp[i]].u);
y=ufs.root(que[qp[i]].v);
if (x==y&&ufs.va[x]==que[qp[i]].a&&ufs.vb[x]==que[qp[i]].b) ans[qp[i]]=;
act.clear();
}
}
for (i=;i<q;i++)
printf(ans[i]?"Yes\n":"No\n");
} int main()
{
// freopen("multiple.in","r",stdin);
// freopen("multiple.out","w",stdout);
putin();
answer();
// fclose(stdin);
// fclose(stdout);
}
multiple
檢測語言 阿尔巴尼亚语 阿拉伯语 阿塞拜疆语 爱尔兰语 爱沙尼亚语 巴斯克语 白俄罗斯语 保加利亚语 冰岛语 波兰语 波斯尼亚语 波斯语 布尔语(南非荷兰语) 丹麦语 德语 俄语 法语 菲律宾语 芬兰语 高棉语 格鲁吉亚语 古吉拉特语 哈萨克语 海地克里奥尔语 韩语 豪萨语 荷兰语 加利西亚语 加泰罗尼亚语 捷克语 卡纳达语 克罗地亚语 拉丁语 拉脱维亚语 老挝语 立陶宛语 罗马尼亚语 马尔加什语 马耳他语 马拉地语 马拉雅拉姆语 马来语 马其顿语 毛利语 蒙古语 孟加拉语 缅甸语 苗语 南非祖鲁语 尼泊尔语 挪威语 旁遮普语 葡萄牙语 齐切瓦语 日语 瑞典语 塞尔维亚语 塞索托语 僧伽罗语 世界语 斯洛伐克语 斯洛文尼亚语 斯瓦希里语 宿务语 索马里语 塔吉克语 泰卢固语 泰米尔语 泰语 土耳其语 威尔士语 乌尔都语 乌克兰语 乌兹别克语 希伯来语 希腊语 西班牙语 匈牙利语 亚美尼亚语 伊博语 意大利语 意第绪语 印地语 印尼巽他语 印尼语 印尼爪哇语 英语 约鲁巴语 越南语 中文简体 中文繁体 |
阿尔巴尼亚语 阿拉伯语 阿塞拜疆语 爱尔兰语 爱沙尼亚语 巴斯克语 白俄罗斯语 保加利亚语 冰岛语 波兰语 波斯尼亚语 波斯语 布尔语(南非荷兰语) 丹麦语 德语 俄语 法语 菲律宾语 芬兰语 高棉语 格鲁吉亚语 古吉拉特语 哈萨克语 海地克里奥尔语 韩语 豪萨语 荷兰语 加利西亚语 加泰罗尼亚语 捷克语 卡纳达语 克罗地亚语 拉丁语 拉脱维亚语 老挝语 立陶宛语 罗马尼亚语 马尔加什语 马耳他语 马拉地语 马拉雅拉姆语 马来语 马其顿语 毛利语 蒙古语 孟加拉语 缅甸语 苗语 南非祖鲁语 尼泊尔语 挪威语 旁遮普语 葡萄牙语 齐切瓦语 日语 瑞典语 塞尔维亚语 塞索托语 僧伽罗语 世界语 斯洛伐克语 斯洛文尼亚语 斯瓦希里语 宿务语 索马里语 塔吉克语 泰卢固语 泰米尔语 泰语 土耳其语 威尔士语 乌尔都语 乌克兰语 乌兹别克语 希伯来语 希腊语 西班牙语 匈牙利语 亚美尼亚语 伊博语 意大利语 意第绪语 印地语 印尼巽他语 印尼语 印尼爪哇语 英语 约鲁巴语 越南语 中文简体 中文繁体 |
[BZOJ 4537][Hnoi 2016]最小公倍数的更多相关文章
- [HNOI 2016]最小公倍数
Description 题库链接 给定一张 \(N\) 个顶点 \(M\) 条边的无向图(顶点编号为 \(1,2,\cdots,n\) ),每条边上带有权值.所有权值都可以分解成 \(2^a\time ...
- bzoj 4540 [HNOI 2016] 序列 - 莫队算法 - Sparse-Table - 单调栈
题目传送门 传送点I 传送点II 题目大意 给定一个长度为$n$的序列.询问区间$[l, r]$的所有不同的子序列的最小值的和. 这里的子序列是连续的.两个子序列不同当且仅当它们的左端点或右端点不同. ...
- [HNOI 2016]树
Description 题库链接 给你一棵 \(N\) 个节点根节点为 \(1\) 的有根树,结点的编号为 \(1\sim N\) :我们称这颗树为模板树.需要通过这棵模板树来构建一颗大树.构建过程如 ...
- [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分
[LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分 题意 给定一个字符串 \(S\), 求有多少种将 \(S\) 的子串拆分为形如 AABB 的拆分方案 \(| ...
- [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩)
[BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩) 题面 给出一棵树和一个图,点数均为n,问有多少种方法把树的节点标号,使得对于树上的任意两个节点u,v,若树上u ...
- [BZOJ 3144][HNOI 2013] 切糕
题目大意 切糕是 (p times q times r) 的长方体,每个点有一个违和感 (v_{x, y, z}).先要水平切开切糕(即对于每个纵轴,切面与其有且只有一个交点),要求水平上相邻两点的切 ...
- BZOJ 4537: [Hnoi2016]最小公倍数 [偏序关系 分块]
4537: [Hnoi2016]最小公倍数 题意:一张边权无向图,多组询问u和v之间有没有一条a最大为a',b最大为b'的路径(不一定是简单路径) 首先想到暴力做法,题目要求就是判断u和v连通,并查集 ...
- bzoj 4537 HNOI2016 最小公倍数
Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,-,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你 ...
- bzoj 4537 最小公倍数
给定一张N个顶点M条边的无向图 每条边上带有权值 所有权值都可以分解成2^a*3^b的形式 q个询问,每次询问给定四个参数u.v.a和b,请你求出是否存在一条顶点u到v之间的路径,使得路径依次经过的边 ...
随机推荐
- VS开发工具 因插件问题导致 已停止工作 解决办法
解决方案如下:No1. 开始-->所有程序-->Microsoft Visual Studio 2012-->Visual Studio Tools-->VS2012 开发人员 ...
- spring boot web 入门
① 新建一个maven项目. ② pom中parent设为 spring-boot-starter-parent .建议使用最新的 RELEASE 版本.否则可能需要设置 <repositori ...
- parse_str
之前没有遇到过parse_str,其意思就是“把查询字符串解析到变量中”也就是$str会被解析为变量. <?php $data = "a=1&b=2";parse_s ...
- 查看服务器是否被DDOS攻击的方法
伴随着现代互联网络快速发展,更加容易出现被攻击.尤其是ddos攻击已经不在是大网站需要关心的事情了.不少中小型企业,也在遭受ddos攻击.站长对ddos攻击不了解,所以网站被ddos攻击的时候,都不会 ...
- python基础===成员访问__len__()和__getitem__()
class A: def __init__(self,*args): self.name = arg pass def __len__(self): return len(self.name) a = ...
- barrier 和 preempt_disable() 学习【转】
#define preempt_disable() \ do{ \ inc_preempt_count(); \ barrier(); \ }while(0) 一.这个barrier 在干什么. ...
- 2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6153 A Secret KMP,思维
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6153 题意:给了串s和t,要求每个t的后缀在在s中的出现次数,然后每个次数乘上对应长度求和. 解法:关 ...
- hdu 4198:Quick out of the Harbour解题报告
Quick out of the Harbour Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- Next Permutation&&Permutation Sequence
Next Permutation Implement next permutation, which rearranges numbers into the lexicographically nex ...
- 更换163的yum源
1.利用oss的文件目录形式进行各地项目的汇总保存.上报在A目录,统计过的放到B目录. 2.各地服务器健康状态检查,每5分钟检查项目, 如果有异常,就发短信+邮件进行汇报.不管是不是有异常,都以 ...