51nod 1515 明辨是非 2017百度之星初赛第一场第二题(并查集+启发式合并)
题目:
原题链接
给n组操作,每组操作形式为x y p。
当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。
当p为0时,如果第x变量和第y个变量可以不相等,则输出YES,并限制他们不相等 ;否则输出NO,并忽略此次操作。
n<=1*10^5
题解:
暑假打百度之星时还傻傻地以为这题就是奇偶游戏(奇偶游戏中变量的值只能是0,1)。
等于有传递性,我们可以用并查集把相同的元素搞在一个集合里。
并查集中,每个联通块的根节点上有一个set,维护的是与这个联通块不同的变量是哪些。
假设现在要求x=y,则x所在联通块的根节点的set中不能含有y所在连通块的根节点,反过来也满足则x可以等于y。
之后就要合并,我们可以把set的size小的合并到set的size大的,注意合并时双向都要改。
假设现在x≠y,则x,y不在一个连通块里即可。注意给set加东西。
最坏情况就是每一次都是两个大小几乎相同的set合并成一个set,这样会转移O(n log n)次,算上set的复杂度,就是O(n log n log n).
本来应该很快的,因为怎么可能轻易达到极限呢。
可是常数有点大,我交了好几次,压线过的。
发现纪中一干大佬都是压线的,于是我很想知道跑300-ms的大佬是怎么卡的.
Code:
#include<set>
#include<cstdio>
#include<algorithm>
#define fo(i, x, y) for(int i = x; i <= y; i ++)
using namespace std;const int N = 1e5 + 5;int n, x, y, p, tot;
int f[N * 2]; set<int> s[N * 2];struct node {int x, y, p;
}a[N];struct node2 {int x, l, r;
}b[N * 2];bool rank_b(node2 a, node2 b) {return a.x < b.x;
}int find(int x) {return f[x] == x ? x : (f[x] = find(f[x]));
}set<int> :: iterator it;void bin(int x, int y) {if(s[x].size() > s[y].size()) swap(x, y);while(!s[x].empty()) {int z = *s[x].begin();s[y].insert(z);s[z].erase(s[z].find(x)); s[z].insert(y);s[x].erase(s[x].begin());}f[x] = y;
}int main() {scanf("%d", &n);fo(i, 1, n) {scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].p);b[++ tot].x = a[i].x; b[tot].l = i; b[tot].r = 0;b[++ tot].x = a[i].y; b[tot].l = i; b[tot].r = 1;}sort(b + 1, b + tot + 1, rank_b);int la = 1; tot = 0; b[n * 2 + 1].x = -1e9;fo(i, 2, n * 2 + 1) if(b[i].x != b[i - 1].x) {++ tot;fo(j, la, i - 1) if(b[j].r) a[b[j].l].y = tot; else a[b[j].l].x = tot;la = i;}fo(i, 1, tot) f[i] = i;fo(i, 1, n) {x = a[i].x; y = a[i].y; p = a[i].p;if(!p) {if(find(x) == find(y)) {printf("NO\n");} else {printf("YES\n");s[f[x]].insert(f[y]); s[f[y]].insert(f[x]);}} else {if(find(x) != find(y)) {if((s[f[x]].count(f[y]) == 0) && (s[f[y]].count(f[x]) == 0)) {printf("YES\n"); bin(f[x], f[y]);} else printf("NO\n");} else printf("YES\n");}}
}
51nod 1515 明辨是非 2017百度之星初赛第一场第二题(并查集+启发式合并)相关推荐
- 2017百度之星初赛第一场题解
前言 这场比赛我卡在线上了,没有进TAT 我只做了三道水题.. 首先是在比赛开始的时候我还在睡觉,我以为是2:30开始.. 然后,由于这个垃圾评测,卡死人了.. 于是我刷新一下,就算了我交了两次,于是 ...
- 2021百度之星初赛第一场部分题解
写在前面 几个家长要求我写一些2021百度之星初赛第一场的题解. 1003 鸽子 原题链接 https://acm.hdu.edu.cn/showproblem.php?pid=6998 http:/ ...
- 2017百度之星初赛B场总结
(A场因为不可抗力因素(?)没能参加,B场还好算是磕磕碰碰地吃着低保过去了,真的菜呀) Chess Problem Description 車是中国象棋中的一种棋子,它能攻击同一行或同一列中没有其他棋 ...
- 2017百度之星初赛B场第一题Chess--简单杨辉三角问题
Chess Accepts: 1799 Submissions: 5738 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768 ...
- [水]2015百度之星初赛第一场 超级赛亚ACMer
Description 百小度是一个ACMer,也是一个超级赛亚人,每个ACMer都有一个战斗力,包括百小度. 所谓超级赛亚人的定义,是说如果在对抗中刚好接近极限状态,那就会激发斗志,实力提升. 具 ...
- 2017 计蒜之道 初赛 第一场 A题B题
阿里九游开放平台近日上架了一款新的益智类游戏--成三棋.成三棋是我国非常古老的一个双人棋类游戏,其棋盘如下图所示: 成三棋的棋盘上有很多条线段,只能在线段交叉点上放入棋子.我们可以用坐标系来描述棋盘: ...
- 2017百度之星初赛
1001 小C的倍数问题 Accepts: 1990 Submissions: 4931 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32 ...
- 2017百度之星初赛:A-1002. 数据分割(并查集+set)
数据分割 Accepts: 102 Submissions: 1332 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
- 2017百度之星初赛:A-1005. 今夕何夕
今夕何夕 Accepts: 1345 Submissions: 5533 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/ ...
最新文章
- 【工具】WPS安卓电脑无广告版
- 一篇文章弄懂Java反射基础和反射的应用场景
- 【若依(ruoyi)】数据选择对话框
- LabVIEW之安装队列工具包AMC安装问题解决
- win11没有uefi如何安装 windows11跳过uefi模式的安装方法
- Nordic Blue Tooth
- 高斯—若尔当(约当)消元法解异或方程组+bitset优化模板
- 系泊系统悬链线matlab,基 于 悬 链 线 理 论 的 系 泊 系 统 势 能
- 2018最新中国知名区块链公司排行榜
- Linux驱动 | DS18B20驱动编程
- 解决问题的能力和个人学习能力总结。
- arcgis弧段怎么加很多点_关于ArcGIS的这62个常用技巧,你造吗?
- 海康IPC摄像头通过ONVIF协议接入VCN离线
- 水晶五笔下载地址(非技术)
- ValueError: cannot resize this array: it does not own its data
- 有极性(电解电容)与无极性电容
- 2018 中国大陆网速排名世界 141 位;Linux 4.18 内核发布
- Spring Boot 配置文件这样加密,才足够安全!
- DIY组装无人机电机+电调+电池+桨叶搭配知识
- 联想g510拆键盘的简单方法_联想Z500笔记本更换键盘图文简单教程
热门文章
- Java方法的参数传递解析
- ASCII码对应表chr(9)、chr(10)、chr(13)、chr(32)、chr(34)、chr(39)
- 《ASP.NET Core 6框架揭秘》实例演示[10]:Options基本编程模式
- [面试] 没礼貌比没专业更可怕(转的和大家一起分享)
- Spark三种部署方式
- hadoop 透明加密先关命令
- 微星 Creator Z17 评测
- python学什么就业前景好_学python和人工智能就业前景怎么样?哪个薪资高?
- Li‘s 核磁共振影像数据处理-1(下)-DWI基础
- 微信小游戏开发入门(一)-基础知识