P5443

Sol

分块 + 可撤销并查集好题。

假设对于每 B 个操作分一块暴力做:

对于没修改到的边,暴力加入并查集,复杂度 O(m)

对于修改到的边,最多 B 条,按边权排序,询问也按边权排序,那么可以双指针和并查集做到 O(B2logn)
这里可以注意到前面没修改的边每次不用重新加入,只需要回退即可。

总复杂度为 O(qB(m+B2logn))=O(qmB+qBlogn),根据均值不等式可以得到 Bmlogn 最优。

代码:

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
#define debug(x) cerr << #x << ' ' << x << endl
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 2000010;
int n;
struct type {
	int op,t,x,y;
}a[N];
int all[N],k;
struct BIT {
	int c[N];
	int lowbit (int x) {
		return x & -x;
	}
	void modify (int x,int d) {
		for (int i = x;i <= n;i += lowbit (i)) c[i] += d;
	}
	int query (int x) {
		int ans = 0;
		for (int i = x;i;i -= lowbit (i)) ans += c[i];
		return ans;
	}
}c1,c2;
void mian () {
	cin >> n;
	for (int i = 1;i <= n;i++) {
		int op;
		cin >> op;
		if (op == 1) {
			int t,x,y;
			cin >> t >> x >> y;
			all[++k] = x;
			a[i] = {op,t,x,y};
		}
		else {
			int t;
			cin >> t;
			a[i] = {op,t,0,0};
		}
	}
	sort (all + 1,all + k + 1);
	k = unique (all + 1,all + k + 1) - all - 1;
	auto find = [&](int x) {
		return lower_bound (all + 1,all + k + 1,x) - all;
	};
	for (int i = 1;i <= n;i++) {
		if (a[i].op == 1) a[i].x = find (a[i].x);
	}
	int sum2 = 0;
	for (int i = 1;i <= n;i++) {
		int p,d;
		if (a[i].op == 1) p = i,d = 1;
		else p = a[i].t,d = -1;
		if (!a[p].t) c1.modify (a[p].x,a[p].y * d);
		else c2.modify (a[p].x + 1,a[p].y * d),sum2 += a[p].y * d;
		int s1 = 0,s2 = sum2;
		int f1 = 0,f2 = 0;
		int p1 = 0,p2 = 0;
		for (int i = 20;i >= 0;i--) {
			int np = p1 + (1 << i),ns1 = s1 + c1.c[np],ns2 = s2 - c2.c[np];
			if (np > k) continue;
			if (ns1 < ns2) {
				p1 = np;
				s1 = ns1,s2 = ns2;
			}
		}
		f1 = s1;
		if (p1 < k) {
			s1 = 0,s2 = sum2;
			f2 = min (c1.query (p1 + 1),sum2 - c2.query (p1 + 1));
			for (int i = 20;i >= 0;i--) {
				int np = p2 + (1 << i),ns1 = s1 + c1.c[np],ns2 = s2 - c2.c[np];
				if (np > k) continue;
				if (ns1 < ns2 || min (ns1,ns2) == f2) {
					p2 = np;
					s1 = ns1,s2 = ns2;
				}
			}
		}
		if (!max (f1,f2)) puts ("Peace");
		else if (f1 > f2) cout << all[p1] << ' ' << f1 * 2 << endl;
		else cout << all[p2] << ' ' << f2 * 2 << endl;
	}
}
int main () {
	int T = 1;
	// cin >> T;
	while (T--) mian ();
	return 0;
}
posted @   incra  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示