Extending Set of Points

我们能发现, 如果把x轴y轴看成点, 那么答案就是在各个连通块里面的x轴的个数乘以y轴的个数之和。

然后就变成了一个并查集的问题, 但是这个题目里面有撤销的操作, 所以我们要把加入和撤销操作变成

这个点影响(L , R)之间的询问, 然后把它丢到线段树里面分成log段, 然后我们dfs一遍线段树, 用按秩合并
并查集取维护, 回溯的时候将并查集撤销。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long using namespace std; const int N = 3e5 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ;
const double eps = 1e-;
const double PI = acos(-); int n;
LL ans[N];
map<PII, int> Map; int fa[N << ], cntx[N << ], cnty[N << ], sz[N << ];
LL now = ; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
vector<PII> vc[N << ];
void Insert(int L, int R, PII e, int l, int r, int rt) {
if(l >= L && r <= R) {
vc[rt].push_back(e);
return;
}
int mid = l + r >> ;
if(L <= mid) Insert(L, R, e, lson);
if(R > mid) Insert(L, R, e, rson);
} int getRoot(int x) {
return fa[x] == x ? x : getRoot(fa[x]);
} void Merge(int x, int y, stack<PII>& stk) {
int fax = getRoot(x);
int fay = getRoot(y);
if(fax != fay) {
if(sz[fax] < sz[fay]) swap(fax, fay);
stk.push(mk(fax, fay));
now -= 1ll * cntx[fax] * cnty[fax];
now -= 1ll * cntx[fay] * cnty[fay];
sz[fax] += sz[fay];
cntx[fax] += cntx[fay];
cnty[fax] += cnty[fay];
fa[fay] = fax;
now += 1ll * cntx[fax] * cnty[fax];
}
} void Delete(stack<PII>& stk) {
while(!stk.empty()) {
int fax = stk.top().fi;
int fay = stk.top().se;
stk.pop();
now -= 1ll * cntx[fax] * cnty[fax];
sz[fax] -= sz[fay];
cntx[fax] -= cntx[fay];
cnty[fax] -= cnty[fay];
fa[fay] = fay;
now += 1ll * cntx[fax] * cnty[fax];
now += 1ll * cntx[fay] * cnty[fay];
}
} void dfs(int l, int r, int rt) {
stack<PII> stk;
for(auto& t : vc[rt]) Merge(t.fi, t.se, stk);
if(l == r) ans[l] = now;
else {
int mid = l + r >> ;
dfs(l, mid, rt << );
dfs(mid + , r, rt << | );
}
Delete(stk);
} int main() {
scanf("%d", &n);
for(int i = ; i <= n; i++) {
PII e; scanf("%d%d", &e.fi, &e.se);
e.se += ;
if(Map.find(e) == Map.end()) {
Map[e] = i;
} else {
Insert(Map[e], i - , e, , n, );
Map.erase(e);
}
}
for(auto& t : Map) Insert(t.se, n, t.fi, , n, );
for(int i = ; i <= ; i++) fa[i] = i, cntx[i] = , sz[i] = ;
for(int i = ; i <= ; i++) fa[i] = i, cnty[i] = , sz[i] = ;
dfs(, n, );
for(int i = ; i <= n; i++) printf("%lld ", ans[i]);
puts("");
return ;
} /*
*/

Codeforces 1140F Extending Set of Points 线段树 + 按秩合并并查集 (看题解)的更多相关文章

  1. Codeforces 1140F Extending Set of Points (线段树分治+并查集)

    这题有以下几个步骤 1.离线处理出每个点的作用范围 2.根据线段树得出作用范围 3.根据分治把每个范围内的点记录和处理 #include<bits/stdc++.h> using name ...

  2. 【CF576E】Painting Edges 线段树按时间分治+并查集

    [CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...

  3. BZOJ_4025_二分图_线段树按时间分治+并查集

    BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...

  4. BZOJ.3673/3674.可持久化并查集(可持久化线段树 按秩合并/启发式合并)

    BZOJ 3673 BZOJ 3674(加强版) 如果每次操作最多只修改一个点的fa[],那么我们可以借助可持久化线段树来O(logn)做到.如果不考虑找fa[]的过程,时空复杂度都是O(logn). ...

  5. CF1140F Extending Set of Points 【按时间分治,并查集】

    题目链接:洛谷 首先我们考虑没有撤回操作的情况,就是将每一行和每一列看做一个点(代表行的称为白点,代表列的称为黑点),每个点$(x,y)$看做一条边. Extend操作实际上就是$x_1$行与$y_1 ...

  6. 线段树区间离散化维护按秩合并并查集(可撤销)——牛客多校第八场E

    模板题..去网上学了可撤销的并查集.. /* 给定一个无向图,边的属性为(u,v,l,r),表示<u,v>可以通过的size为[l,r] 求出有多少不同的size可以从1->n 把每 ...

  7. [Codeforces 266E]More Queries to Array...(线段树+二项式定理)

    [Codeforces 266E]More Queries to Array...(线段树+二项式定理) 题面 维护一个长度为\(n\)的序列\(a\),\(m\)个操作 区间赋值为\(x\) 查询\ ...

  8. [Codeforces 280D]k-Maximum Subsequence Sum(线段树)

    [Codeforces 280D]k-Maximum Subsequence Sum(线段树) 题面 给出一个序列,序列里面的数有正有负,有两种操作 1.单点修改 2.区间查询,在区间中选出至多k个不 ...

  9. codeforces 1217E E. Sum Queries? (线段树

    codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...

随机推荐

  1. VS下载Github的项目引用报错

    错误如下 1.添加新的Nuget包源 添加新的源 https://www.nuget.org/api/v2/ 2.还原Nuget包 3.升级Visual Studio到最新 工具-->获取工具和 ...

  2. sysstat-----获取服务器负载历史记录

    sysstat工具与负载历史回放 很多系统负载过高的时候我们是无法立即获知或者立即解决的,当检测到或者知道历史的高负载状况时,可能需要回放历史监控数据,这时 sar 命令就派上用场了,sar命令同样来 ...

  3. 什么是orm思想?

    什么是orm思想? 1.hibernate使用orm思想对数据库进行crud操作 2.在web阶段学习javabean更正确的叫法是:实体类 3.orm: object   relational   ...

  4. RianbowDesign

    换了很多个名字,最后换成这个. 主要考虑把自己所学的.所经历的都结合到一起,用这种方式来保持热情. 算是一个设计网站,管理咨询,游戏设计,平面logo之类,想最多地攘括到里边.就像自己不确定的主业一样 ...

  5. 设置 Confluence 6 外部索引站点

    Confluence 并不能比较容易的对外部站点进行搜索,这个是因为 Confluence 使用的是 Lucene 内部查找,但是你还是有下面 2 个可选的方案: 嵌入外部页面到 Confluence ...

  6. Confluence 6 导入模板的步骤

    第一步:检查你 Confluence 站点中安装的模板组件 查看当前已经导入到你 Confluence 站点中可用的模板组件: 以系统管理员或者 Confluence 管理员权限登录 Confluen ...

  7. Git- 连接远程仓库

    如何使用Git 连接远程仓库呢?远程仓库->一般指的是代码托管平台.那就先来瞅瞅三个较熟悉的版本(代码)托管服务平台. 版本(代码)托管服务平台: 码云(gitee.com):是开源中国社区团队 ...

  8. Exception类的学习与继承总结

    日期:2018.11.11 星期日 博客期:023 Exception类的学习与继承总结 说起来我们上课还是说过的!老师提到了报错问题出现主要分Exception和Error两类!第一次遇见这个问题是 ...

  9. Django项目的创建及基本使用

    安装步骤 Django是Python进行Web开发的框架,目前应用比较广泛.使用python进行Web开发,能够很快的搭建所需的项目,可以运用于原型开发,也可以部署到实际的应用环境. 使用Django ...

  10. python - 发送带各种类型附件的邮件

    如何发送各种类型的附件. 基本思路就是,使用MIMEMultipart来标示这个邮件是多个部分组成的,然后attach各个部分.如果是附件,则add_header加入附件的声明. 在python中,M ...