CF1140F Extending Set of Points 【按时间分治,并查集】
题目链接:洛谷
首先我们考虑没有撤回操作的情况,就是将每一行和每一列看做一个点(代表行的称为白点,代表列的称为黑点),每个点$(x,y)$看做一条边。
Extend操作实际上就是$x_1$行与$y_1,y_2$列联通,$x_2$行与$y_1$列联通时,$x_2$行也跟$y_2$列联通。
同一个联通块里的一个黑点和一个白点会产生1的贡献,所以就是连边操作+查询每个联通块的(黑点个数*白点个数)之和,可以使用并查集维护。
现在考虑撤回操作,其实就相当于每条边在$[t_1,t_2]$这段时间里“有贡献”,考虑建一个关于时间的线段树,将$[t_1,t_2]$拆分为log个区间,然后将这条边加入这log个区间对应的边集中,表示在这个区间的范围中这条边“有贡献”。
然后对这个线段树进行dfs,每次dfs到一个区间$[l,r]$的时候,将这个区间对应的边集的边加入并查集,退出的时候把影响消除。
其实对于大部分非均摊时间的数据结构都是可以很快撤回的,并查集也是这样。所以不能使用路径压缩,要使用按秩合并。
时间复杂度$O(n\log^2n)$
#include<bits/stdc++.h>
#define Rint register int
#define fi first
#define se second
#define mp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int N = ;
int q, fa[N], siz[N][], top;
map<pii, int> ma;
vector<pii> vec[N << ];
LL ans, ansx[N];
inline int getfa(int x){
return x == fa[x] ? x : getfa(fa[x]);
}
pii que[N];
inline void comb(int x, int y){
x = getfa(x); y = getfa(y);
if(x == y) return;
if(siz[x][] + siz[x][] < siz[y][] + siz[y][]) swap(x, y);
ans += (LL) siz[x][] * siz[y][] + (LL) siz[x][] * siz[y][];
siz[x][] += siz[y][];
siz[x][] += siz[y][];
fa[y] = x;
que[++ top] = mp(x, y);
}
inline void undo(int x, int y){
fa[y] = y;
siz[x][] -= siz[y][];
siz[x][] -= siz[y][];
ans -= (LL) siz[x][] * siz[y][] + (LL) siz[x][] * siz[y][];
}
inline void update(int x, int L, int R, int l, int r, pii val){
if(l <= L && R <= r){
vec[x].push_back(val);
return;
}
int mid = L + R >> ;
if(l <= mid) update(x << , L, mid, l, r, val);
if(mid < r) update(x << | , mid + , R, l, r, val);
}
inline void dfs(int x, int L, int R){
int now = top;
for(pii tmp : vec[x])
comb(tmp.fi, tmp.se);
if(L == R) ansx[L] = ans;
else {
int mid = L + R >> ;
dfs(x << , L, mid); dfs(x << | , mid + , R);
}
while(top > now){
undo(que[top].fi, que[top].se); -- top;
}
}
int main(){
scanf("%d", &q);
for(Rint i = ;i <= q;i ++){
int x, y;
scanf("%d%d", &x, &y); y += 3e5;
if(!ma.count(mp(x, y))) ma[mp(x, y)] = i;
else {
update(, , q, ma[mp(x, y)], i - , mp(x, y));
ma.erase(mp(x, y));
}
}
for(auto it = ma.begin();it != ma.end();it ++)
update(, , q, it -> se, q, it -> fi);
for(Rint i = ;i <= 3e5;i ++) fa[i] = i, siz[i][] = ;
for(Rint i = 3e5 + ;i <= 6e5;i ++) fa[i] = i, siz[i][] = ;
dfs(, , q);
for(Rint i = ;i <= q;i ++) printf("%lld\n", ansx[i]);
}
CF1140F
CF1140F Extending Set of Points 【按时间分治,并查集】的更多相关文章
- Codeforces 1140F Extending Set of Points (线段树分治+并查集)
这题有以下几个步骤 1.离线处理出每个点的作用范围 2.根据线段树得出作用范围 3.根据分治把每个范围内的点记录和处理 #include<bits/stdc++.h> using name ...
- 【CF576E】Painting Edges 线段树按时间分治+并查集
[CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...
- BZOJ_4025_二分图_线段树按时间分治+并查集
BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...
- 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)
传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...
- CF1140F - Extending Set of Points
题意:对于点集S,定义函数F(S)为对S不断扩展到不能扩展时S的点数.一次扩展定义为如果有一个平行于坐标轴的矩形的三个点在S中,则第四个点加入S. 动态在S中加点删点,每次操作完后求F(S)的值. 解 ...
- BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...
- 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 ...
- 【CF603E】Pastoral Oddities cdq分治+并查集
[CF603E]Pastoral Oddities 题意:有n个点,依次加入m条边权为$l_i$的无向边,每次加入后询问:当前图是否存在一个生成子图,满足所有点的度数都是奇数.如果有,输出这个生成子图 ...
- Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)
题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...
随机推荐
- Python3 使用pygal 生成世界人口地图
最近在看<python从入门到实践>,其中有一个例子是使用pygal制作世界人口地图,觉得挺有意思的,这里就记录下来了, 其实代码不是很复杂,使用环境环境python3.废话不多说,直接上 ...
- (java实现)双向循环链表
什么是双向循环链表 在了解双向循环链表之前,如果对链表还没有一个清晰的概念,建议你看看单链表和单向循环链表,这有利于你更好的理解下面的内容.(废话有点多[逃] 相比单链表,双向循环链表是一个更加复杂的 ...
- 决心学HTML 第一晚
老师数他的审美观不行,怕教的我们的审美观也不行,所以,就不讲HTML了,但是期末又要考, 自己英语又不行,期末做项目又要用,我可能又要做组长,只能硬着头皮自学了. 所以,现在从第一页开始学!!! 这这 ...
- VisualSVN 关于权限(第2篇)
最终的答案: 仓库本身不能给他增加访问权限,必须增加否则连不上,不增加的时候 他默认就是No Access: 仓库本身可以理解为:祖宗,他是访问权限的根基.子目录会继承他的权限. 那么既然必须给他增加 ...
- windows开机自动执行bat脚本启动cmd命令窗口并执行命令,最后自动关闭cmd命令窗
先说bat脚本吧,随便在桌面建一个文本文档,在里面写脚本,内容是,先启动cmd命令窗,并执行一个命令,最后自动关闭cmd窗,如下: ---------------------------------- ...
- C#的预处理指令
- Django中使用xadmin作为后台管理页面
xadmin后台管理 安装:luffy虚拟环境下 # >: pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 ...
- 爬虫保存Cookie
import http.cookiejar as cookielib session.cookie = cookielib.LWPCookieJar() session.cookie.save(fil ...
- init system
参考:5 Best Modern Linux ‘init’ Systems (1992-2015) 参考:Linux开机流程 参考:<鸟哥的 Linux 私房菜:基础学习篇 第四版>第十七 ...
- 02.python网络爬虫第二弹(http和https协议)
一.HTTP协议 1.官方概念: HTTP协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(www.world wide web) 服务器传输超 ...