Codeforces 1140F 线段树 分治 并查集
题意及思路:https://blog.csdn.net/u013534123/article/details/89010251
之前cf有一个和这个相似的题,不过那个题只有合并操作,没有删除操作,直接并查集搞一搞就行了。对于这个题,因为有删除操作,我们对操作序列建一颗线段树,记录每个操作影响的区间操作就可以了。这里的并查集不能路径压缩,要按秩合并,这样复杂度是O(logn)的。
代码:
#include <bits/stdc++.h>
#define ls (o << 1)
#define rs (o << 1 | 1)
#define INF 0x3f3f3f3f
#define db double
#define pii pair<int, int>
#define LL long long
using namespace std;
const int maxn = 300010;
const int Base = 300000;
vector<pii> tr[maxn * 4];
map<pii, int> mp;
map<pii, int>::iterator it;
LL res[maxn], cnt_x[maxn * 2], cnt_y[maxn * 2], sz[maxn * 2];
int f[maxn * 2];
LL ans;
pii a[maxn];
int get(int x) {
if(x == f[x]) return x;
return get(f[x]);
}
void add(int o, int l, int r, int ql, int qr, pii val) {
if(l >= ql &&r <= qr) {
tr[o].push_back(val);
return;
}
int mid = (l + r) >> 1;
if(ql <= mid) add(ls, l, mid, ql, qr, val);
if(qr > mid) add(rs, mid + 1, r, ql, qr, val);
}
void del(int x, int y) {
int x1 = get(x), y1 = get(y);
if(x1 != y1) return;
ans -= cnt_x[x] * cnt_y[x];
cnt_x[x] -= cnt_x[y], cnt_y[x] -= cnt_y[y];
sz[x] -= sz[y];
ans += cnt_x[x] * cnt_y[x];
ans += cnt_x[y] * cnt_y[y];
f[y] = y;
}
pii merge(int x, int y) {
int x1 = get(x), y1 = get(y);
if(x1 == y1) return make_pair(-1, -1);
if(sz[x1] < sz[y1]) swap(x1, y1);
ans -= cnt_x[x1] * cnt_y[x1];
ans -= cnt_x[y1] * cnt_y[y1];
sz[x1] += sz[y1];
cnt_x[x1] += cnt_x[y1], cnt_y[x1] += cnt_y[y1];
ans += cnt_x[x1] * cnt_y[x1];
f[y1] = x1;
return make_pair(x1, y1);
}
void dfs(int o, int l, int r) {
if(l == 12) {
l++;
l--;
}
stack<pii> s;
for (auto x : tr[o]) {
pii tmp = merge(x.first, x.second);
if(tmp.first != -1) s.push(tmp);
}
if(l == r) res[l] = ans;
else {
int mid = (l + r) >> 1;
dfs(ls, l, mid);
dfs(rs, mid + 1, r);
}
while(!s.empty()) {
del(s.top().first, s.top().second);
s.pop();
}
}
int main() {
int n, x, y;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &x, &y);
y += Base;
a[i] = make_pair(x, y);
if(mp.find(a[i]) == mp.end()) mp[a[i]] = i;
else {
add(1, 1, n, mp[a[i]], i - 1, a[i]);
mp.erase(a[i]);
}
}
for (it = mp.begin(); it != mp.end(); it++) {
add(1, 1, n, it -> second, n, it -> first);
}
for (int i = 1; i <= Base; i++) {
f[i] = i, cnt_x[i] = 1, cnt_y[i] = 0, sz[i] = 1;
}
for (int i = Base + 1; i <= Base * 2; i++) {
f[i] = i, cnt_x[i] = 0, cnt_y[i] = 1, sz[i] = 1;
}
dfs(1, 1, n);
for (int i = 1; i <= n; i++)
printf("%lld ", res[i]);
}
Codeforces 1140F 线段树 分治 并查集的更多相关文章
- 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)
传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...
- bzoj4025二分图(线段树分治 并查集)
/* 思维难度几乎没有, 就是线段树分治check二分图 判断是否为二分图可以通过维护lct看看是否链接出奇环 然后发现不用lct, 并查集维护奇偶性即可 但是复杂度明明一样哈 */ #include ...
- BZOJ3237:[AHOI2013]连通图(线段树分治,并查集)
Description Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connec ...
- BZOJ4025 二分图(线段树分治+并查集)
之前学了一下线段树分治,这还是第一次写.思想其实挺好理解,即离线后把一个操作影响到的时间段拆成线段树上的区间,并标记永久化.之后一块处理,对于某个节点表示的时间段,影响到他的就是该节点一直到线段树根的 ...
- Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)
题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...
- BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树分治+并查集)
传送门 解题思路 可以离线,然后确定每个边的出现时间,算这个排序即可.然后就可以线段树分治了,连通性用并查集维护,因为要撤销,所以要按秩合并,时间复杂度\(O(nlog^2 n)\) 代码 #incl ...
- BZOJ3237 AHOI2013连通图(线段树分治+并查集)
把查询看做是在一条时间轴上.那么每条边都有几段存在时间.于是线段树分治就好了. 然而在bzoj上t掉了,不知道是常数大了还是写挂了. 以及brk不知道是啥做数组名过不了编译. #include< ...
- Codeforces 1140F Extending Set of Points (线段树分治+并查集)
这题有以下几个步骤 1.离线处理出每个点的作用范围 2.根据线段树得出作用范围 3.根据分治把每个范围内的点记录和处理 #include<bits/stdc++.h> using name ...
- [BZOJ4025]二分图(线段树分治,并查集)
4025: 二分图 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2191 Solved: 800[Submit][Status][Discuss] ...
随机推荐
- 力扣——3sum closest(最接近的三数之和)python 实现
题目描述: 中文: 给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一 ...
- Axure 部件的交互样式
选中的 时 需要设置事件
- 二分图最大权匹配——KM算法
前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...
- AI加持的阿里云飞天大数据平台技术揭秘
摘要:2019云栖大会大数据&AI专场,阿里云智能计算平台事业部研究员关涛.资深专家徐晟来为我们分享<AI加持的阿里云飞天大数据平台技术揭秘>.本文主要讲了三大部分,一是原创技术优 ...
- TIM4定时器功能设置
一.初始化过程 /*********************************************************************** 利用TIM4定时器作为计时,每个0.1 ...
- jekins—持续集成
json转换为Python的字典形式 Martin fowler:通过自动化的构建,编译-发布-自动化测试,尽早的发现集成的错误 持续集成的要素: 统一的代码库 自动构建编译 自动测试(单元测试) 每 ...
- xcode Delete current line
Delete a line like eclipse CTRL+D (tested on Xcode 4.5.1) : First of all, change these rights : sudo ...
- asp.net ToString() 输出格式详细
C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToString("D5") 00025 E 科学型 25000.ToString ...
- (转)使用OpenGL显示图像(二)定义Shapes
定义形状 编写:jdneo - 原文:http://developer.android.com/training/graphics/opengl/shapes.html 在一个OpenGL ES Vi ...
- (转)使用OpenGL ES显示图像
编写:jdneo - 原文:http://developer.android.com/training/graphics/opengl/index.html 转:http://hukai.me/and ...