贼ex的一道,卡了本仙女整整7个小时orz

思路容易理解,but码力very重要orz
我愿意花五毛钱提升我的码力,换个脑子也行,不换脸这张脸生得俊俏
luogu传送door

题目

在宇宙一个不为人知的地方,有一个星球,上面有一个国家,只有数学家居住。 在这个国家有n个数学家,有趣的是,每个数学家都住在自己的城市,且城市间无道路相连,因为他们可以在线交流。当然,城市有从1到n的编号。

一位数学家决定用手机发论文,而手机将“不言而喻”自动更正成了“猜谜游戏”。 不久之后,这个国家就发现了猜谜游戏。他们想要见面一起玩,于是这个国家就开始了修路工程。 道路修建会持续m天。对于第i天,若gcd(a,b)=m−i+1,则a和b城市间会修一条路。

由于数学家们忙于建筑工作,请你来确定一对数学家最早什么时候能凑到一起玩。

输入输出格式
输入格式
第一行有三个正整数n,m,q,表示城市数量、修路持续天数、询问数量。 接下来q行,每行有两个正整数a,b,表示询问a和b两个城市的数学家最早什么时候能在一起玩。

输出格式
输出q行,第i行有一个正整数,表示第i次询问的结果

说明
数据范围:
对于40%的数据:n≤4000,q≤10 ^5

对于全部数据:
1≤n,q≤10^5

1≤m≤n1≤m≤n

样例1解释: 在第一天,(3,6)(3,6)之间修了一条路,因此第二次询问输出1
在第二天,(2,4),(2,6),(2,8),(4,6),(6,8)(2,4),(2,6),(2,8),(4,6),(6,8)之间都修了一条路,此时44和88号城市连通,第三次询问输出2
在第三天,所有编号互质的城市之间都修了路,2和5号城市在此时连通,第一次询问输出1

样例2解释: 在第二天,(20,15)之间修了一条路
第四天,(15,9)之间修了一条路
所以20和9号城市在第四天连通,输出4

题解

我看了luogu题解,发现根本没有人跟宝宝是一个做法,当时,我的妈呀!
俺内心慌得一批,但是我在这条不归路上继续走了下去,误入歧途啊
七个小时终于把这个江山打下来了
肯定很好想,问这两个城市有没有相通,肯定是我们的并查集大哥,这个不用多说!
而且1与任何数都互质,那么在最后一天施完工后肯定所有城市都是互通的,
这就是一棵赤裸裸的树

我们真正要解决的就是这两个城市在第几天成为了一个集合

帅气的我的实现是先预处理每一天,哪些城市会进行施工相通,边处理,边并查集,这样的话就不用把所有的边全部得到后再sort再并查集。
因为从m到1循环的话,i,j之间没路时,这天就是最早的 ,

PS:并查集的unionSet一定要用优化的启发式,不然就等着TLE回家找妈妈吧!
反正我是把长城都哭淹了!我们在进行unionSet时顺便建个有向边,
一定是爸爸之间建边,又哭了orz

接着就是dfs,不一定是从1开始,可以用循环找根节点f[i]==i,哭了哭了。
dfs处理每一个点的深度,而且可以保证每个点的入度不会大于1,在处理深度的同时,把u,v两点第几天相同的也记录下来,用vector可以办到

最后就是爬树,妙啊!妙啊!暴力lca都行的老铁,
因为每个点都只有一个爸爸 (诶)
所以这棵树也是唯一的,路径唯一的,
我们就在线操作,x,y用一个Max记录x和y在往上爬的时候路径的最大值

以上听起来是不是很简单啊woo~

代码实现

瞅瞅吧!七个小时的改了n遍,长得惨不忍睹啊!这浓缩的都是精华啊!
还有rank标记数组,rank是关键字,又哭了哭了orz,泪腺炸了

#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define MAXN 100005
#define LL long long
struct node {int v, w;node () {}node ( int A, int B ) {v = A;w = B;}
}depth[MAXN];
int n, m, q, cnt;
int f[MAXN];
int ran[MAXN];
vector < node > tree[MAXN];
void makeSet () {for ( int i = 1;i <= n;i ++ )f[i] = i;
}
int findSet ( int x ) {while ( x != f[x] ) x = f[x];return x;
}
void unionSet ( int x, int y, int w ) {int u = findSet( x ); int v = findSet( y );if ( u == v ) return;if ( ran[u] > ran[v] ) {f[v] = u;tree[u].push_back ( node ( v, w ) );}else {f[u] = v;if( ran[u] == ran[v] )ran[v] ++;tree[v].push_back ( node ( u, w ) );}
}
void dfs ( int x, int dep, int val ) {if ( depth[x].v ) return;depth[x].v = dep;depth[x].w = val;for ( int i = 0;i < tree[x].size();i ++ ) {int v = tree[x][i].v, w = tree[x][i].w;dfs ( v, dep + 1, w );}
}
int Max = 0;
void lca ( int x, int y ) {while ( depth[x].v > depth[y].v ) {Max = max ( depth[x].w, Max );x = f[x];}while ( depth[y].v > depth[x].v ) {Max = max ( depth[y].w, Max );y = f[y];}while ( x != y ) {Max = max ( depth[x].w, Max );Max = max ( depth[y].w, Max );x = f[x];y = f[y];}
}
int main() {scanf ( "%d %d %d", &n, &m, &q );makeSet ();for ( int i = m;i >= 1;i -- )for ( int j = i * 2;j <= n;j += i )if ( findSet ( j - i ) != findSet ( j ) )unionSet ( j - i, j, m - i + 1 );for ( int i = 1;i <= n;i ++ )if ( f[i] == i ) {dfs ( i, 1, 0 );break;}for ( int i = 1;i <= q;i ++ ) {int a, b;scanf ( "%d %d", &a, &b );Max = 0; lca ( a, b );printf ( "%d\n", Max );    }return 0;
}

把这道题A(≧▽≦)/啦啦啦

好了,像打了鸡血吃兴奋剂一样,有任何代码,思路不懂得欢迎留言,欢迎欢迎热烈欢迎,我们不卖假,诚信营业,做出世界前五百强!byebye~不要太想帅气又多金的我!

[COCI2017-2018#5] Pictionary(并查集+dfs)相关推荐

  1. 2018/8/9 MultiU 6 并查集+dfs,反向建边提高查询效率 !!! / 最大字段和n维(降维)/ 状压+中途相遇法...

    hdu6370 Werewolf http://acm.hdu.edu.cn/showproblem.php?pid=6370 题意:村民只能说真话,狼人"可以"撒谎,每个人说一句 ...

  2. zoj 3761 Easy billiards 并查集+dfs

    生活真是奇妙的东西,这样的题目居然能被联想到这样的算法,只能说智商不够啊. 这道题目的意思不解释了,月赛的时候我队友已经想出来了做法,但是我们最后还是没A. 题解: 1.首先将所有能连接的球连接起来, ...

  3. UVA - 208 Firetruck(并查集+dfs)

    题目: 给出一个结点d和一个无向图中所有的边,按字典序输出这个无向图中所有从1到d的路径. 思路: 1.看到紫书上的提示,如果不预先判断结点1是否能直接到达结点d,上来就直接dfs搜索的话会超时,于是 ...

  4. 【51Nod - 1416】两点 (dfs 或 并查集+dfs)

    题干: 福克斯在玩一款手机解迷游戏,这个游戏叫做"两点".基础级别的时候是在一个n×m单元上玩的.像这样:     每一个单元有包含一个有色点.我们将用不同的大写字母来表示不同的颜 ...

  5. Multiplayer Moo[ [ 并查集+dfs连通块 ] / [ dfs ] ]

    题目链接 题目描述: The cows have come up with a creative new game, surprisingly giving it the least creative ...

  6. HDU1181:变形课(并查集 + DFS + BFS)

    变形课 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submissi ...

  7. 一笔画问题 (DFS或并查集)

    题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=42 一笔画问题是欧拉回路的一个变形,可以一笔画的条件有两个:1.所有顶点必须连通  2. ...

  8. 连通图的判断(并查集, DFS, BFS)

    首先要明确什么是连通图??? 连通图:对于一个图来说,图中的任意一个点都能访问到所有的点,则说明该图连通 很明显,如果要判断一个图是否连通,则必须要从任意一个搜索一遍,判断是否到达了所有的点,则很快会 ...

  9. PAT甲级1021 Deepest Root :[C++题解]树的最大深度、并查集、dfs求树的深度

    文章目录 题目分析 题目链接 题目分析 分析: 考察知识点:并查集.dfs.树的深度 给定n个结点,n-1条边,只要能保证只有1个连通分量,就是一棵树.否则的话就不是树,它是不连通的. 用并查集来看是 ...

最新文章

  1. BRCM5.02编译五: fatal error: uuid/uuid.h: No such file or directory compilation terminated
  2. 利用python进行识别相似图片(二)
  3. JDBC+Servlet+JSP整合开发之22.JSP简介
  4. [社会趣闻]储户召集7名亲友占满银行窗口 每次存一元
  5. zookeeper集群部署(分布式)
  6. SQLite数据库常用语句及MAC上的SQLite可视化工具MeasSQLlite使用
  7. 【三】版本之间穿梭切换
  8. NLog 2.0.0.2000 使用实例
  9. CentOS使用 Crontab定时任务清理程序日志
  10. 人工神经网络图像识别,人脸识别神经网络模型
  11. html按钮调用php函数,如何在html按钮上执行php函数点击
  12. python画气泡图_用python 来绘制气泡图的简单技巧
  13. CREO二维CAD图纸导出1:1比例导出,单位为mm
  14. 冷库用电量计算机方式,冷库一般用电量如何估算
  15. 查看nginx是否启动成功
  16. 高防CDN是如何防护网站被攻击的
  17. 19 kafka消息队列
  18. [攻略][Python]给array类型的数据添加方括号、去掉方括号
  19. 漫步凸分析十一——分离定理
  20. uni-app-console

热门文章

  1. 炸锅了!Google称2029年人类开始实现永生不死!疾病,衰老,痛苦将彻底消失!?
  2. position定位 响应式_使用 Vue3 实现双盒子定位 Overlay
  3. solr 配置mysql数据源_solr data-config.xml配置文件的见解mysql数据源
  4. oracle 产看执行计划_ODBA 技能SPM计划
  5. php网页连mysql_php - 如何在单个网页上连接多个MySQL数据库?
  6. cmosfixr插件怎么用_3dmax插件神器|怎么用3dmax插件神器去完成背景墙的效果图设计?...
  7. java string底层实现_Java-学习日记(Shell与String底层原理)
  8. iphone4 base64 mp3 无法解析 html5,javascript - 如何使用HTML5在firefox上播放base64音频数据? - 堆栈内存溢出...
  9. mysql新加不了数据库_MySQL数据库之mysql增加新用户无法登陆解决方法
  10. python人工智能面试题_人工智能面试题分享(含答案)