首页 > 其他分享 >【luogu CF1140F】Extending Set of Points(线段树分治)

【luogu CF1140F】Extending Set of Points(线段树分治)

时间:2022-10-20 10:48:32浏览次数:102  
标签:CF1140F Set int luogu ny y0 include

Extending Set of Points

题目链接:luogu CF1140F

题目大意

有一个点集,有一个扩展操作是加入符合条件的 (x0,y0) 直到不能加入位置。
符合条件是原来 (x0,y0) 不存在而且存在 (a,b) 使得 (a,b),(a,y0),(x0,b) 都在点集中。
然后一开始点集为空,会加入或者删除点集,每次问你如果要扩展最后点集有多少个点,注意不会真的扩展。

思路

考虑到怎样会扩展,就是你比如有一列的点,列的位置是一个集合 S,然后某个位置的点所在的行有一个点。
那这个点的那里一列上所有 S 集合上的位置最后都会扩展的有点。

那你发现,如果行和列给它分别建点,然后一个点就把它所在的行和列连边。
首先是二分图,接着你根据上面的性质,其实只要某个行点能走到某个列点,那这个行列的位置就会有点。
那总结一下最后会形成一个类似矩形,每个行的和每个列的线形成的所有交点都有点。
那就是你行点的个数乘列点的个数。

于是处理好了一次的情况,考虑多次询问。
发现是插入和删除,那每个点出现的时刻是一个区间。
然后并查集的话你要删除也不是不行,改成按秩合并。
但是要按顺序删除,按栈的顺序,所以我们上线段树分治即可。

代码

#include<map>
#include<cstdio>
#include<vector>
#define ll long long

using namespace std;

const int N = 3e5 + 100;
int n;
map <pair <int, int>, int> a;
ll ans[N];

struct Bing_cha_ji {
	int sta[N], fa[N << 1];
	ll ans, nx[N << 1], ny[N << 1];
	
	void Init() {
		for (int i = 1; i <= n + n; i++) fa[i] = i;
		for (int i = 1; i <= n; i++) nx[i] = 1, ny[i + n] = 1;
	}
	
	int find(int now) {
		if (fa[now] == now) return now;
		return find(fa[now]);
	}
	
	void insert(pair <int, int> W) {
		int x = W.first, y = W.second + n;
		x = find(x); y = find(y); if (x == y) return ;
		ans -= nx[x] * ny[x] + nx[y] * ny[y];
		if (nx[x] + ny[x] <= nx[y] + ny[y]) swap(x, y);
		fa[y] = x; sta[++sta[0]] = y; nx[x] += nx[y]; ny[x] += ny[y];
		ans += nx[x] * ny[x];
	}
	
	void pop() {
		int y = sta[sta[0]--], x = fa[y];
		ans -= nx[x] * ny[x];
		nx[x] -= nx[y]; ny[x] -= ny[y];
		fa[y] = y; ans += nx[x] * ny[x] + nx[y] * ny[y];
	}
}B;

struct XD_tree {
	vector <pair<int, int> > f[N << 2];
	
	void insert(int now, int l, int r, int L, int R, pair <int, int> x) {
		if (L <= l && r <= R) {
			f[now].push_back(x); return ;
		}
		int mid = (l + r) >> 1;
		if (L <= mid) insert(now << 1, l, mid, L, R, x);
		if (mid < R) insert(now << 1 | 1, mid + 1, r, L, R, x);
	}
	
	void build(int now, int l, int r) {
		int lst = B.sta[0];
		for (int i = 0; i < f[now].size(); i++) B.insert(f[now][i]);
		if (l == r) {
			ans[l] = B.ans;
			while (B.sta[0] > lst) B.pop();
			return ;
		}
		int mid = (l + r) >> 1;
		build(now << 1, l, mid); build(now << 1 | 1, mid + 1, r);
		while (B.sta[0] > lst) B.pop();
	}
}T;

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		int x, y; scanf("%d %d", &x, &y);
		if (!a[make_pair(x, y)]) {
			a[make_pair(x, y)] = i;
		}
		else {
			T.insert(1, 1, n, a[make_pair(x, y)], i - 1, make_pair(x, y));
			a.erase(make_pair(x, y));
		}
	}
	for (map <pair <int, int>, int> ::iterator it = a.begin(); it != a.end(); it++) T.insert(1, 1, n, it->second, n, it->first);
	
	B.Init(); T.build(1, 1, n);
	for (int i = 1; i <= n; i++) printf("%lld ", ans[i]);
	
	return 0;
}

标签:CF1140F,Set,int,luogu,ny,y0,include
From: https://www.cnblogs.com/Sakura-TJH/p/luogu_CF1140F.html

相关文章

  • 小程序的this.data和this.setdata
    this.data是用来获取页面data对象的,而this.setData是用来更新界面的。用this.setData({})用于将数据从逻辑层发送到视图层(异步),同时改变对应的this.data的值(同步)。用thi......
  • How to get the return value of the setTimeout inner function in js All In One
    HowtogetthereturnvalueofthesetTimeoutinnerfunctioninjsAllInOne在js中如何获取setTimeout内部函数的返回值✅Promisewrap&Async/Await......
  • K8S之StatefulSet控制器
    无状态应用进程客户端的每次连接均可独立地处理,一次请求和响应即构成一个完整的事务,它们不受已完成的连接或现有其他连接的影响,且意外中断或关闭时仅需要重新建立连接即可,因......
  • 【Kubernetes】K8s笔记(九):DaemonSet 守护进程集
    目录0.Deployment有哪些不足1.使用YAML描述DaemonSet对象2.在Kubernetes里使用DaemonSet3.Taint和Toleration4.静态PodkubernetesDaemonSetdocs0.Dep......
  • K8S statefulset
       StatefulSet详解kubectlexplainsts.spec:主要字段解释replicas:副本数selector:那个pod是由自己管理的serviceName:必须关联到一个无头服务商template:定义pod模......
  • antd 中 清空Input组件中的值,不是通过form.setFiledValue的方式,非受控组件清空值
    今天看到一篇不错的文章关于antform不通过react的state设置非受控组件值的文章,转发记录一下:(以下为原文) 最近做了一个业务就是在输入框中处理防抖的业务,本来就可以,测试......
  • DataSet与DataLoaders使用教程
    title:DataSet与DataLoaders使用教程mathjax:truedate:2022-10-0409:13:43tags:DataSetDataLoaderDataSet与DataLoaders使用教程4、PyTorch的Dataset与Data......
  • FFmpeg中转场滤镜xfade的时间参数(duration和offset)与算法解读
    xfade转场滤镜小科普最近在研究音视频合成的相关功能,现已有两个视频剪辑。拼合成一个文件显然用concat可以完成,但是过渡生硬,而xfade滤镜可以很方便实现更加缓和的场景切换。......
  • mybatis_24_设置(settings)_useColumnLabel
    useColumnLabel使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。值:true(默认)/false<settings><settingn......
  • mybatis_25_设置(settings)_useGeneratedKeys
    useGeneratedKeys允许JDBC支持自动生成主键,需要数据库驱动支持。如果设置为true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作。值:true/false(......