正解:分块+并查集

解题报告:

传送门!

真的好神仙昂QAQ,,,完全想不出来,,,还是太菜了QAQ

首先还是要说下,这题可以用K-D Tree乱搞过去(数据结构是个好东西昂,,,要多学学QAQ),但是我不会,暂时也不打算学更不打算写这种方法,所以只是提一下可以用这个姿势过去QAQ

然后说下另外一个方法,神仙一般的(分块+并查集),,,

首先要get一个套路,是这样儿的:

对于这种有两种限制的题目

一般的套路就是条件按照第一种权值为关键字排序,询问按照第二种关键字排序

然后对于条件先按第一关键字分块,然后在块内部按第二关键字排序

这样当前块前面的点都是符合当前询问点对于第一关建字条件的

而且第二关键字都是单调的,所以就可以two−pointers扫一下

然后对于每个询问,暴力处理一下当前块的贡献

然后回归这道题,首先可以想到这道题的话,为了方便区分给定条件和询问,在这里define一下,条件是ab询问是AB

显然最小公倍数的话就是说amax=A,bmax=B嘛

首先考虑到显然可以先把a>A,b>B的都排除了

然后就可以考虑可不可以把剩下的合法的连起来,然后用个并查集维护一下两个点是否连起来了,然后再判断一下联通块内的amax&bmax是否等于A,B

然后具体做法就是

对条件按a排序并分个块,然后把块内部的边按b排序,对询问按B排序

然后对每个块分别做,设当前块的还麻油按照b排序的时候的左端点的a为li右端点的a为ri

然后先找出所有a在[li,ri]的询问

考虑到对第i个块的第j个询问,有贡献的条件有哪些

1)前面i-1个块中的b<Bj的边

因为考虑到最初块是按a排序的,即使是在内部排序之后也是能保证前面i-1块中的任意一条边的a<当前块中的a

所以只要是b满足条件就好

这里又考虑到已经对于询问按照B排序了,那如果前面i-1块的b也是按顺序的,就可以直接two-pointers做了,所以就再对前i-1块整体按b排个序

2)当前第i块中满足b<Bj,a<Aj的边

分块的中心思想不是就,大段维护,局部朴素嘛

这里考虑到反正每个块都只有√m条边,所以直接暴力地做就好

但是还要想一个问题

显然是可能有对之前的询问满足条件但是对当前询问不满足条件了的嘛

所以如果对他们做并查集的时候就要考虑怎么撤销

如果全部重新建一个并查集肯定也是布星的,因为前面那个第一种情况是不用撤销的昂

所以考虑就不用路径压缩了,但还是要优化一下不然过不去,所以用个按秩合并

然后就做完辣!484很妙QAQ!

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define rg register
#define gc getchar()
#define rp(i,x,y) for(rg int i=x;i<=y;++i)
#define my(i,x,y) for(rg int i=x;i>=y;--i) const int N=+,M=+,sqN=+;
int n,m,q,fa[N],blk,sz[N],amx[N],bmx[N],cnt,siz,r[sqN],as[N],ed_tmp,sz_tmp[N];
struct ed{int fr,to,a,b,bl;}edge[M],ques[N],tmp[N],tmptmp[N]; il int read()
{
char ch=gc;int x=;bool y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il bool cmpa(ed gd,ed gs){return gd.a==gs.a?gd.b<gs.b:gd.a<gs.a;}
il bool cmpb(ed gd,ed gs){return gd.b==gs.b?gd.a<gs.a:gd.b<gs.b;}
il void clr(){rp(i,,n)fa[i]=i,sz[i]=,amx[i]=bmx[i]=-;cnt=;}
il int fd(int x){return fa[x]==x?x:fd(fa[x]);}
il void mg(int x,int y,int a,int b)
{
int fax=fd(x),fay=fd(y);if(sz[fax]>sz[fay])swap(fax,fay);
tmptmp[++ed_tmp]=(ed){fax,fay,amx[fay],bmx[fay],sz[fay]};
if(fax^fay)fa[fax]=fay,sz[fay]+=sz[fax],amx[fay]=max(amx[fay],amx[fax]),bmx[fay]=max(bmx[fay],bmx[fax]);
amx[fay]=max(amx[fay],a);bmx[fay]=max(bmx[fay],b);
} int main()
{
n=read();m=read();blk=sqrt(m*log2(n));rp(i,,m)edge[i]=(ed){read(),read(),read(),read(),};q=read();rp(i,,q)ques[i]=(ed){read(),read(),read(),read(),i};
sort(edge+,edge++m,cmpa);sort(ques+,ques++q,cmpb);rp(i,,m)edge[i].bl=(i-)/blk+,r[(i-)/blk+]=i;siz=edge[m].bl;
rp(i,,siz)
{
clr();
rp(j,,q)if(edge[r[i-]+].a<=ques[j].a && (edge[r[i-]++blk].a>ques[j].a || r[i-]++blk>m))tmp[++cnt]=ques[j];if(!cnt)continue;
if(i^)sort(edge+,edge+r[i-]+,cmpb);int rpoint=;
rp(j,,cnt)
{
while(rpoint<r[i-]+ && edge[rpoint].b<=tmp[j].b)mg(edge[rpoint].fr,edge[rpoint].to,edge[rpoint].a,edge[rpoint].b),++rpoint;
ed_tmp=;
rp(k,r[i-]+,min(r[i-]+blk,m))if(edge[k].a<=tmp[j].a && edge[k].b<=tmp[j].b)mg(edge[k].fr,edge[k].to,edge[k].a,edge[k].b);
int fr=fd(tmp[j].fr),to=fd(tmp[j].to);
as[tmp[j].bl]=(fr==to && amx[fr]==tmp[j].a && bmx[fr]==tmp[j].b);
my(k,ed_tmp,)fr=tmptmp[k].fr,to=tmptmp[k].to,fa[fr]=fr,amx[to]=tmptmp[k].a,bmx[to]=tmptmp[k].b,sz[to]=tmptmp[k].bl;
ed_tmp=;
}
}
rp(i,,q)as[i]?printf("Yes\n"):printf("No\n");
return ;
}

然后这儿是代码QAQ!

洛谷P3247 最小公倍数 [HNOI2016] 分块+并查集的更多相关文章

  1. 题解 洛谷 P3247 【[HNOI2016]最小公倍数】

    题意可以转化为是否能找一条从\(u\)到\(v\)的路径,经过的边的\(a\)和\(b\)的最大值恰好都是询问所给定的值. 若只有\(a\)的限制,可以将询问离线,对边和询问都从小到大排序,然后双指针 ...

  2. Bzoj1015/洛谷P1197 [JSOI2008]星球大战(并查集)

    题面 Bzoj 洛谷 题解 考虑离线做法,逆序处理,一个一个星球的加入.用并查集维护一下连通性就好了. 具体来说,先将被消灭的星球储存下来,先将没有被消灭的星球用并查集并在一起,这样做可以路径压缩,然 ...

  3. 洛谷1525 关押罪犯NOIP2010 并查集

    问题描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两 ...

  4. 洛谷P1525 关押罪犯(并查集、二分图判定)

    本人蒟蒻,只能靠题解AC,看到大佬们的解题思路,%%%%%% https://www.luogu.org/problemnew/show/P1525 题目描述 S城现有两座监狱,一共关押着N名罪犯,编 ...

  5. 洛谷 P2661 信息传递 Label:并查集||强联通分量

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  6. 洛谷 P1111 修复公路 Label:并查集

    题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你什么时 ...

  7. 洛谷P3367 【模板】并查集

    P3367 [模板]并查集 293通过 551提交 题目提供者HansBug 标签 难度普及- 提交  讨论  题解 最新讨论 不知道哪错了 为啥通不过最后三个节点 题解 不懂为什么MLE 最后一个数 ...

  8. 洛谷 P3367 【模板】并查集

    P3367 [模板]并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数 ...

  9. 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树

    正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...

随机推荐

  1. [转载][IoC容器Unity]第二回:Lifetime Managers生命周期

    1.引言 Unity的生命周期是注册的类型对象的生命周期,而Unity默认情况下会自动帮我们维护好这些对象的生命周期,我们也可以显示配置对象的生命周期,Unity将按照配置自动管理,非常方便,下面就介 ...

  2. 深刻理解Python中的元类(metaclass)【转】

    译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...

  3. React Native常用组件之ScrollView

    1. 两个要点 1.1 ScrollView必须有一个确定的高度才能正常工作 它实际上所做的就是将一系列不确定高度的子组件装进一个确定高度的容器(通过滚动操作) 通常有两种做法: 第一种: 直接给该S ...

  4. myeclipse创建hibernate工程

    1.创建数据库: from blog http://www.cnblogs.com/zhaocundang/p/9061959.html 使用navicat mysql IDE: 创建数据库 book ...

  5. 求教如何在win7 X64系统上安装.net 3.5 sp1

    其实win7系统已自带net 3.5.1了.开始菜单——控制面板——程序——打开或关闭windows功能,找到Microsoft .NET Framework 3.5.1,去掉选项,确定.然后再进入“ ...

  6. QT Graphics-View 3D编程例子- 3D Model Viewer

    学习在Graphics-View框架中使用opengl进行3D编程,在网上找了一个不错的例子“3D Model Viewer”,很值得学习. 可以在http://www.oyonale.com/acc ...

  7. php info

    http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/08/12/1797753.html  php pdo 相关 http://blog.cs ...

  8. iPhone 上你可能还不知道的小技巧

    用了这么久的 iPhone,这些技巧你可能都还不知道哦. 1.怎么用耳机切歌? 将耳机的话筒部位的中间(平时暂停用的,按一下)连按两下 即可. 连按两下,下一首. 连按三下,上一首. 2.摇一摇,相当 ...

  9. 跨服务器做yum源

    服务器无法上网,然后自己根据光盘搭建的YUM源不够用.RPM安装软件,各种依赖,找包烦死. 先做个 能上外网的 http proxy 找一个可以上Internet的服务器,然后起一个squid服务, ...

  10. springboot之thymeleaf学习

    这是springboot的view层不建议使用jsp,而是thymeleaf,虽然我也不知道为什么,但是后来可能会明白一些.学springBoot也遇到很多bug,导致脱累了进度.有点类似于jsp,但 ...