题意:对于点集S,定义函数F(S)为对S不断扩展到不能扩展时S的点数。一次扩展定义为如果有一个平行于坐标轴的矩形的三个点在S中,则第四个点加入S。

动态在S中加点删点,每次操作完后求F(S)的值。

解:首先有个结论就是,把这些点用平行于坐标轴的线段连接起来,则E值为每个连通块的横坐标种数 * 纵坐标种数之和。

线段树分治 + 可回退化并查集,O(nlog2n)。

 #include <bits/stdc++.h>

 typedef long long LL;
const int N = ; struct Node {
int x, y;
Node(int X, int Y) {
x = X;
y = Y;
}
}; std::map<int, int> mp[N];
int n, m;
LL ans[N];
std::vector<Node> v[N << ]; namespace ufs { struct opt {
int x, y;
opt(){}
opt(int X, int Y) {
x = X, y = Y;
}
}stk[N * ]; int top; int fa[N * ], siz[N * ], s1[N * ], s2[N * ], clock;
LL tot, stk2[N];
inline void init() {
for(int i = ; i < N; i++) {
fa[i] = i;
fa[i + N] = i + N;
siz[i] = siz[i + N] = ;
s1[i] = s2[i + N] = ;
s2[i] = s1[i + N] = ;
}
top = clock = ;
return;
}
int find(int x) {
if(x == fa[x]) return x;
return find(fa[x]);
}
inline LL cal(int x) {
return 1ll * s1[x] * s2[x];
}
inline void merge(int x, int y) {
x = find(x);
y = find(y);
if(x == y) return;
if(siz[x] < siz[y]) {
std::swap(x, y);
}
stk2[++clock] = tot;
tot -= cal(x) + cal(y);
stk[++top] = opt(y, fa[y]);
fa[y] = x;
stk[++top] = opt(x, siz[x]);
siz[x] += siz[y];
stk[++top] = opt(x, s1[x]);
s1[x] += s1[y];
stk[++top] = opt(x, s2[x]);
s2[x] += s2[y];
tot += cal(x);
return;
}
inline void erase(int t) {
while(clock > t) {
tot = stk2[clock--];
s2[stk[top].x] = stk[top].y;
top--;
s1[stk[top].x] = stk[top].y;
top--;
siz[stk[top].x] = stk[top].y;
top--;
fa[stk[top].x] = stk[top].y;
top--;
}
return;
}
} void add(int L, int R, Node x, int l, int r, int o) {
if(L <= l && r <= R) {
v[o].push_back(x);
return;
}
int mid = (l + r) >> ;
if(L <= mid) {
add(L, R, x, l, mid, o << );
}
if(mid < R) {
add(L, R, x, mid + , r, o << | );
}
return;
} void solve(int l, int r, int o) {
int now = ufs::clock;
for(int i = ; i < (int)v[o].size(); i++) {
ufs::merge(v[o][i].x, v[o][i].y + N);
//printf("[%d %d] merge %d %d \n", l, r, v[o][i].x, v[o][i].y);
}
if(l == r) {
ans[r] = ufs::tot;
ufs::erase(now);
return;
}
int mid = (l + r) >> ;
solve(l, mid, o << );
solve(mid + , r, o << | );
ufs::erase(now);
return;
} int main() {
ufs::init();
scanf("%d", &n);
for(int i = , x, y; i <= n; i++) {
scanf("%d%d", &x, &y);
if(mp[x][y]) {
add(mp[x][y], i - , Node(x, y), , n, );
//printf("add : (%d %d) [%d %d] \n", x, y, mp[x][y], i - 1);
mp[x][y] = ;
}
else {
mp[x][y] = i;
}
}
std::map<int, int>::iterator it;
for(int i = ; i < N; i++) {
for(it = mp[i].begin(); it != mp[i].end(); it++) {
if(it->second) {
add(it->second, n, Node(i, it->first), , n, );
//printf("add : (%d %d) [%d %d] \n", i, it->first, it->second, n);
}
}
} solve(, n, );
for(int i = ; i <= n; i++) {
printf("%lld ", ans[i]);
}
return ;
}

AC代码

CF1140F - Extending Set of Points的更多相关文章

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

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

  2. Codeforces 1140F Extending Set of Points 线段树 + 按秩合并并查集 (看题解)

    Extending Set of Points 我们能发现, 如果把x轴y轴看成点, 那么答案就是在各个连通块里面的x轴的个数乘以y轴的个数之和. 然后就变成了一个并查集的问题, 但是这个题目里面有撤 ...

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

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

  4. Educational Codeforces Round 62 (Rated for Div. 2) Solution

    最近省队前联考被杭二成七南外什么的吊锤得布星,拿一场Div. 2恢复信心 然后Div.2 Rk3.Div. 1+Div. 2 Rk9,rating大涨200引起舒适 现在的Div. 2都怎么了,最难题 ...

  5. Embeding Python & Extending Python with FFPython

    Introduction ffpython is a C++ lib, which is to simplify tasks that embed Python and extend Python. ...

  6. (转) Written Memories: Understanding, Deriving and Extending the LSTM

    R2RT   Written Memories: Understanding, Deriving and Extending the LSTM Tue 26 July 2016 When I was ...

  7. [转]Extending the User Interface in Outlook 2010

    本文转自:https://msdn.microsoft.com/en-us/library/office/ee692172%28v=office.14%29.aspx#OfficeOLExtendin ...

  8. 有理数的稠密性(The rational points are dense on the number axis.)

    每一个实数都能用有理数去逼近到任意精确的程度,这就是有理数的稠密性.The rational points are dense on the number axis.

  9. [LeetCode] Max Points on a Line 共线点个数

    Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...

随机推荐

  1. [JZOJ3233] 照片

    题目 题目大意 有一个\(01\)序列.给你一堆区间,每个区间中有且仅有一个\(1\)点. 问最多的\(1\)点个数. 思考历程 感觉这题特别经典,似乎在哪里见过,又好像没有见过. 一开始朝贪心方面想 ...

  2. TopCoder代码格式模板

    $BEGINCUT$ $PROBLEMDESC$ $ENDCUT$ #include<bits/stdc++.h> using namespace std; class $CLASSNAM ...

  3. 学习Caffe(一)使用Caffe

    如何使用Caffe Caffe教程(http://robots.princeton.edu/courses/COS598/2015sp/slides/Caffe/caffe_tutorial.pdf) ...

  4. 数据库小技巧:使用distinct去除重复行

    这里有2个表 问题question表 楼层question_floor表 需求:已知某用户的id为uid,实现“我的回复”功能,即查看我回复的所有问题 遇到的问题:如果直接对question表和que ...

  5. Spring MVC(十四)--SpringMVC验证表单

    在Spring MVC中提供了验证器可以进行服务端校验,所有的验证都必须先注册校验器,不过校验器也是Spring MVC自动加载的,在使用Spring MVC校验器之前首先要下载相关的jar包,下面是 ...

  6. 十条服务器端优化Web性能的技巧总结

    原文地址:http://www.jb51.net/yunying/452723.html 提高 web 应用的性能从来没有比现在更重要过.网络经济的比重一直在增长:全球经济超过 5% 的价值是在因特网 ...

  7. HTTP协议请求篇

    http协议的基本概念 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.是工作在tcp/ip协议基础上的,所有的WWW文件都必须 ...

  8. Mysql优化系列之查询优化干货1

    从这一篇开始,准备总结一些直接受用的sql语句优化,写sql是第二要紧的,第一要紧的,是会分析怎么查最快, 因为当你写过很多sql后,查询出结果已经不是目标,快,才是目标.另外,通过测试和比较的结果才 ...

  9. [POI2013]MOR-Tales of seafaring

    题目 思博题,发现一旦路径太长我们可以来回走最后一条边,但是这样并不能改变路径长度的奇偶性 所以求一下所有点之间奇最短路和偶最短路就好了,直接暴力\(BFS\)即可 有一个烦人的特判 代码 #incl ...

  10. Java多线程设计模式系列

    通过几天的认真阅读,发现这是一本难得一见的好书,为了加深巩固学习成功,我打算将书中的例子全部自己实现一遍,特此记录下来也方便其他朋友学习. 第一章,java语言的线程 单线程程序:打印10000次go ...