题目链接:洛谷

首先我们考虑没有撤回操作的情况,就是将每一行和每一列看做一个点(代表行的称为白点,代表列的称为黑点),每个点$(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)$

 1 #include<bits/stdc++.h>
 2 #define Rint register int
 3 #define fi first
 4 #define se second
 5 #define mp make_pair
 6 using namespace std;
 7 typedef long long LL;
 8 typedef pair<int, int> pii;
 9 const int N = 600003;
10 int q, fa[N], siz[N][2], top;
11 map<pii, int> ma;
12 vector<pii> vec[N << 2];
13 LL ans, ansx[N];
14 inline int getfa(int x){
15     return x == fa[x] ? x : getfa(fa[x]);
16 }
17 pii que[N];
18 inline void comb(int x, int y){
19     x = getfa(x); y = getfa(y);
20     if(x == y) return;
21     if(siz[x][0] + siz[x][1] < siz[y][0] + siz[y][1]) swap(x, y);
22     ans += (LL) siz[x][0] * siz[y][1] + (LL) siz[x][1] * siz[y][0];
23     siz[x][0] += siz[y][0];
24     siz[x][1] += siz[y][1];
25     fa[y] = x;
26     que[++ top] = mp(x, y);
27 }
28 inline void undo(int x, int y){
29     fa[y] = y;
30     siz[x][0] -= siz[y][0];
31     siz[x][1] -= siz[y][1];
32     ans -= (LL) siz[x][0] * siz[y][1] + (LL) siz[x][1] * siz[y][0];
33 }
34 inline void update(int x, int L, int R, int l, int r, pii val){
35     if(l <= L && R <= r){
36         vec[x].push_back(val);
37         return;
38     }
39     int mid = L + R >> 1;
40     if(l <= mid) update(x << 1, L, mid, l, r, val);
41     if(mid < r) update(x << 1 | 1, mid + 1, R, l, r, val);
42 }
43 inline void dfs(int x, int L, int R){
44     int now = top;
45     for(pii tmp : vec[x])
46         comb(tmp.fi, tmp.se);
47     if(L == R) ansx[L] = ans;
48     else {
49         int mid = L + R >> 1;
50         dfs(x << 1, L, mid); dfs(x << 1 | 1, mid + 1, R);
51     }
52     while(top > now){
53         undo(que[top].fi, que[top].se); -- top;
54     }
55 }
56 int main(){
57     scanf("%d", &q);
58     for(Rint i = 1;i <= q;i ++){
59         int x, y;
60         scanf("%d%d", &x, &y); y += 3e5;
61         if(!ma.count(mp(x, y))) ma[mp(x, y)] = i;
62         else {
63             update(1, 1, q, ma[mp(x, y)], i - 1, mp(x, y));
64             ma.erase(mp(x, y));
65         }
66     }
67     for(auto it = ma.begin();it != ma.end();it ++)
68         update(1, 1, q, it -> se, q, it -> fi);
69     for(Rint i = 1;i <= 3e5;i ++) fa[i] = i, siz[i][0] = 1;
70     for(Rint i = 3e5 + 1;i <= 6e5;i ++) fa[i] = i, siz[i][1] = 1;
71     dfs(1, 1, q);
72     for(Rint i = 1;i <= q;i ++) printf("%lld\n", ansx[i]);
73 }

CF1140F

转载于:https://www.cnblogs.com/AThousandMoons/p/11116420.html

CF1140F Extending Set of Points 【按时间分治,并查集】相关推荐

  1. 线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)

    题目链接 题目大意: 你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y ...

  2. CodeForces - 1217F Forced Online Queries Problem(线段树分治+并查集撤销)

    题目链接:点击查看 题目大意:给出 nnn 个点,初始时互相不存在连边,需要执行 mmm 次操作,每次操作分为两种类型: 1xy1 \ x \ y1 x y:如果 (x,y)(x,y)(x,y) 之间 ...

  3. 牛客多校8 - All-Star Game(线段树分治+并查集按秩合并的撤销操作)

    题目链接:点击查看 题目大意:有 n 个球员和 m 个球迷,一个球员可能是多个球迷的粉丝,需要选择最少的球员进行比赛,使得所有的球迷都愿意观看(对于每个球迷来说,都有至少一个其喜欢的球员入选比赛) 对 ...

  4. 【CF603E】Pastoral Oddities cdq分治+并查集

    [CF603E]Pastoral Oddities 题意:有n个点,依次加入m条边权为$l_i$的无向边,每次加入后询问:当前图是否存在一个生成子图,满足所有点的度数都是奇数.如果有,输出这个生成子图 ...

  5. BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树分治+并查集)

    传送门 解题思路 可以离线,然后确定每个边的出现时间,算这个排序即可.然后就可以线段树分治了,连通性用并查集维护,因为要撤销,所以要按秩合并,时间复杂度\(O(nlog^2 n)\) 代码 #incl ...

  6. 【XSY2469】graph 分治 并查集

    题目大意 给你一张\(n\)个点\(m\)条边的无向图,问删去每个点后,原图是不是二分图. \(n,m\leq 100000\) 题解 一个图是二分图\(\Longleftrightarrow\)该图 ...

  7. 越野赛车问题——线段树分治+并查集

    题目 [题目描述] 小 $H$ 是一位优秀的越野赛车女选手.现在她准备在 $A$ 山上进行赛车训练. $A$ 山上一共有 $n$ 个广场,编号依次为 $1$ 到 $n$ ,这些广场之间通过 $n-1$ ...

  8. [BZOJ4320][ShangHai2006]Homework(根号分治+并查集)

    对于<=sqrt(300000)的询问,对每个模数直接记录结果,每次加入新数时暴力更新每个模数的结果. 对于>sqrt(300000)的询问,枚举倍数,每次查询大于等于这个倍数的最小数是多 ...

  9. bzoj4025-二分图【线段树分治,并查集】

    正题 题目链接:https://darkbzoj.tk/problem/4025 题目大意 nnn个点mmm条边,每条边会在一个TTT以内的时间段内出现,对于任意一个TTT以内的时刻求图是否是一个二分 ...

最新文章

  1. adb 连接不上电脑怎么办?
  2. 怎样把centos 6.2 系统里的网卡em1还原为eth0
  3. LaTeX半小时速成究极进化版(修改版)
  4. SQL语言之索引(Oracle)
  5. Bit-Z为什么成为熊市之光?
  6. R3 data related to category and hierarchy mapping logic in CRM
  7. 【youcans 的 OpenCV 例程200篇】113. 形态学操作之腐蚀
  8. ios8中百度推送接收不到
  9. Protel99SE教程(二)——PCB封装
  10. 数学之路-数据分析进阶-转化率
  11. ExamDiff Pro(电脑文件对比工具)官方正式版V12.0.1.8 | 最好用的文件对比工具之一文件内容对比工具下载
  12. 判断字符串是否是邮箱或者手机号码格式
  13. POJ 1252 Euro Efficiency G++ 完全背包 背
  14. FPGA Nios II学习笔记一
  15. 无盘服务器 安装客户机程序,顺网云服务端和客户端安装
  16. 每月一书(202111):《五百年来王阳明》
  17. python代码风格指南_记录Python代码:完整指南
  18. win10+ ubuntu16.04 双系统及无线、输入法、deepin-wineQQ微信等配置(亲测)
  19. 饱受争议的闪电网络,能在2020年迎来大爆发吗?
  20. Android ExpandableListView 使用实例

热门文章

  1. 【编译原理】求一个句型短语、直接短语、句柄(一看就懂~!骗小狗)
  2. python【数据结构与算法】一种时间复杂度和空间复杂度的计算方法
  3. 在sublime中让html和css链接
  4. 服务器内存一般多大_各类网站服务器内存多大才合适?
  5. android input 点击事件失效,在textinputedittext android上不会触发onclick事件
  6. 浅析刚刚起步的创业公司应该如何选择适合自己的网站类型呢?
  7. php reactphp wss_workerman的基本用法(示例详解)
  8. matlab负荷预测,负荷预测matlab
  9. 开发日记-20190802 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 18
  10. 思科安全:加密流量威胁检测、加密流量威胁和恶意软件检测、识别无线干扰或威胁、Talos 情报源可加强对已知和新型威胁的防御、分布式安全异常检测...