洛谷P3247 最小公倍数 [HNOI2016] 分块+并查集
正解:分块+并查集
解题报告:
真的好神仙昂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] 分块+并查集的更多相关文章
- 题解 洛谷 P3247 【[HNOI2016]最小公倍数】
题意可以转化为是否能找一条从\(u\)到\(v\)的路径,经过的边的\(a\)和\(b\)的最大值恰好都是询问所给定的值. 若只有\(a\)的限制,可以将询问离线,对边和询问都从小到大排序,然后双指针 ...
- Bzoj1015/洛谷P1197 [JSOI2008]星球大战(并查集)
题面 Bzoj 洛谷 题解 考虑离线做法,逆序处理,一个一个星球的加入.用并查集维护一下连通性就好了. 具体来说,先将被消灭的星球储存下来,先将没有被消灭的星球用并查集并在一起,这样做可以路径压缩,然 ...
- 洛谷1525 关押罪犯NOIP2010 并查集
问题描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两 ...
- 洛谷P1525 关押罪犯(并查集、二分图判定)
本人蒟蒻,只能靠题解AC,看到大佬们的解题思路,%%%%%% https://www.luogu.org/problemnew/show/P1525 题目描述 S城现有两座监狱,一共关押着N名罪犯,编 ...
- 洛谷 P2661 信息传递 Label:并查集||强联通分量
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- 洛谷 P1111 修复公路 Label:并查集
题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你什么时 ...
- 洛谷P3367 【模板】并查集
P3367 [模板]并查集 293通过 551提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 不知道哪错了 为啥通不过最后三个节点 题解 不懂为什么MLE 最后一个数 ...
- 洛谷 P3367 【模板】并查集
P3367 [模板]并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数 ...
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
随机推荐
- debian/deepin 15.3 15.4安装jdk 1.7 (或jdk 7),配置默认环境
一.前言 Deepin 15.3是基于Debian开发的,安装jdk 1.7有所不同,默认是openjdk-8-jdk,而我们玩一些编译需要的是jdk 7. 所以本文给出安装JDK 7的教程. Dee ...
- Java知多少(59)创建多线程
到目前为止,我们仅用到两个线程:主线程和一个子线程.然而,你的程序可以创建所需的更多线程.例如,下面的程序创建了三个子线程: // Create multiple threads. class New ...
- ajax实战用法详解
谦虚使人进步,总结使人提高! 以下5个方法执行一般Ajax请求的简短形式,在处理复杂的Ajax请求时应该使用jQuery.ajax() 1.load(url,[data],[callback])载入远 ...
- Android 使用ColorMatrix改变图片颜色
原文链接:http://blog.csdn.net/janice0529/article/details/49207939 ColorMatrix的颜色矩阵介绍 颜色矩阵M是一个5*4的矩阵,在And ...
- android TV选中时高亮凸显效果
链接: http://pan.baidu.com/s/1pLjAFQ7 密码: xb8g <ignore_js_op> 360手机助手截图0410_18_02_01.png (335.64 ...
- [Bayes] Parameter estimation by Sampling
虽然openBugs效果不错,但原理是什么呢?需要感性认识,才能得其精髓. Recall [Bayes] prod: M-H: Independence Sampler firstly. 采样法 Re ...
- asp.net mvc 3.0 知识点整理 ----- (3).HtmlHelper(Html 辅助方法)介绍
在View视图中,Html的类型是System.Web.Mvc.HtmlHelper<T>, 所有的辅助方法都需要和ModelState交互.那么,ModelState是什么呢?它是模型绑 ...
- ThinkingInJava 学习 之 0000002 操作符
1. 更简单的打印语句 2. 使用Java操作符 3. 优先级(单目乘除位关系,逻辑三目后赋值) 4. 赋值 1. 方法调用中的别名问题 5. 算术操作符 6. 自动递增和递减 7. 关系操作符 1. ...
- 4. Oracle数据库用户管理备份与恢复
一. Oracle用户管理备份介绍 Oracle物理备份核心就是将物理文件拷贝一份副本:存放在磁盘上.物理文件指的是:数据文件,控制文件,日志文件,参数文件等等. 根据数据库状态而分:备份可分为热备份 ...
- QT开发环境安装配置教程
QT开发环境安装配置教程 分类: QT2012-11-29 23:31 35366人阅读 评论(12) 收藏 举报 Linux版的直接在ubutnu软件中心输入QT,安装响应的Designer,Cre ...