矩形填补
2016-07-08 15:42
253 查看
问题描述 Problem Description
给定平面 n 个黑点,如果平面一个边平行于坐标轴的矩形 3 个角是黑色的那么就把那个矩形的第 4 个角改成黑色,最后平面上将会有多少个黑点输入描述 Input Description
第一行一个整数 n ,表示最初有 n 个点接下来 n 行,每行两个整数 xi,yi,表示第 i 个点的坐标
输出描述 Output Description
一个整数,表示最后有多少个点输入样例 Sample Input
[1]
31 1
1 2
2 2
[2]
50 0
1 0
0 1
1 2
2 1
输出样例 Sample Output
[1]
4[2]
9数据范围 Data Size
30% 的数据 n≤100100% 的数据 n≤2∗105;|xi|,|yi|≤109
分析 I Think
因为 x,y 十分巨大,所以要用离散化,弱弱的我还只会用 map 。对于任意一个点 (xi,yi) ,我们将 xi 与 yi 连边,这样子,如果存在 (x1,y1),(x1,y2),(x2,y1) 的话,第四个点 (x2,y2) 也被连在一起了。
至于统计点的数量,如果 a 个 x 值和 b 个 y 值被连在一起,那么总计有 a∗b 个点,记 fi 表示以 i 为根的树中有多少个 x 值, gi 表示以 i 为根的树中有多少个 y 值, 最后答案就是 ∑fi∗gi ,每次合并时顺便合并一下 f,g 就可以了。
代码 Code
#include <cstdio> #include <cstring> #include <algorithm> #include <map> using namespace std; typedef long long LL; const LL add = 10000000000; int father[400040]; int f[400040]; int g[400040]; map<LL,int>turn; LL n,t; void read(LL &); int find(int); void uni(int,int); int main(){ read(n); for(int i=1;i<=(n<<1);++i) father[i] = i; for(LL i=1,x,y;i<=n;++i){ read(x); read(y); y += add; if(turn.find(x) == turn.end()){ turn.insert(pair<LL,int>(x,++t)); f[t] = 1; g[t] = 0; } if(turn.find(y) == turn.end()){ turn.insert(pair<LL,int>(y,++t)); f[t] = 0; g[t] = 1; } uni(turn[x],turn[y]); } LL ans = 0; for(int i=1;i<=t;++i) if(father[i] == i) ans += (LL)f[i]*g[i]; printf("%lld",ans); return 0; } void read(LL &_in){ _in = 0; LL flag = 1; char ch = getchar(); while(ch!='-' && (ch>'9'||ch<'0')) ch = getchar(); if(ch == '-'){ flag = -1; ch = getchar(); } while(ch>='0' && ch<='9'){ _in = _in*10+ch-'0'; ch = getchar(); } _in *= flag; } int find(int x){ if(x != father[x]) father[x] = find(father[x]); return father[x]; } void uni(int x,int y){ int p = find(x); int q = find(y); if(p == q) return ; f[q] += f[p]; g[q] += g[p]; f[p] = g[p] = 0; father[p] = q; }
相关文章推荐
- Linux服务器宕机案例第二则
- MySQL使用hugepage
- JS中变量名作为if条件的 true/flase
- FIFO 和 LRU 调度算法
- 字符串拼接 针对in条件
- 台湾电子产业转型面临考验
- Oracle Sales Cloud简单介绍
- Ubuntu update: Failed to fetch, Hash sum mismatch
- Codeforces Round #199 (Div. 2) -- C. Cupboard and Balloons (数学)
- linux 内存调优
- 网络视频播放Vitamio第三方
- mysql 插入时判断重复时更新
- 实体类-时间类(零点后经过秒数换算为时、分、秒)(Modifying the Internal Data Representation of a Class)
- 【log4net】配置
- SSL小记
- Buttons(按钮)
- bzoj1084(dp)
- Error:(16, 0) Gradle DSL method not found: 'android()'
- 【bzoj2286】[Sdoi2011消耗战 虚树+dp
- CentOS 6.5 搭建 LAMP 环境