正解:分块+并查集

解题报告:

传送门!

真的好神仙昂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. WebApi XML,Json格式自定义,IEnumerable<T>,ArrayOf

    global.ascx中application-start() GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSeri ...

  2. vue处理用户输入

    为了让用户和你的应用进行互动,可以用 v-on 指令绑定一个监听事件用于调用我们 Vue 实例中定义的方法: <div id="app-5"> <p>{{ ...

  3. git配置用户名邮箱,全局配置/单仓库配置

    在项目根目录下进行单仓库配置(作用域只在本仓库下): git config user.name "gitlab's Name" git config user.email &quo ...

  4. Linux系统备份与恢复

    序言:前面一篇文章简单地介绍了Linux系统备份与恢复的相关概念,这里接着上一篇介绍两个常用的备份与恢复命令. 1  常见的备份命令 在介绍下面的备份恢复命令之前先简单的说明一下: 如果我们只是要实现 ...

  5. PHP最全笔记(五)(值得收藏,不时翻看一下)

    // 删除 方法1:将其值设置为空字符串 setcookie('user[name]', ''); 方法2:将目标cookie设为“已过期”状态. //将cookie的生存时间设置为过期,则生存期限与 ...

  6. Springboot学习笔记(六)-配置化注入

    前言 前面写过一个Springboot学习笔记(一)-线程池的简化及使用,发现有个缺陷,打个比方,我这个线程池写在一个公用服务中,各项参数都定死了,现在有两个服务要调用它,一个服务的线程数通常很多,而 ...

  7. Java并发之volatile二

    使用volatilekeyword的场景 Volatile 变量具有 synchronized 的可见性特性.可是不具备原子特性.这就是说线程可以自己主动发现 volatile 变量的最新值.Vola ...

  8. (转) at&T语法格式 与 at&T - intel格式对比

    原地址 示例: movl (%ebp), %eax, 等同于Intel格式中的 ] ,AT&T中,源操作数在左,目的操作数在右.“l”是Longword,相当于Intel格式中的dword p ...

  9. ElasticSearch在linux上的安装部署全程记录

    由于项目需求,需要在linux平台搭建一套ES服务.在搭建过程中,遇到各种各样的问题.后来都一一解决.现在要记录下来这个过程,以及其中遇到的问题,及其解决方法. 一.环境配置 操作系统:Cent OS ...

  10. 《objective-c基础教程》学习笔记(二)—— for循环的基本应用

    在上一篇博文中,我们介绍了如何开发前期的准备,以及简单的类型输出实例. 这篇博文,我要记录一个for循环输出的实例.并对此展开,改变成不同的三个小函数. int main(int argc, cons ...