P5443

Sol

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

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

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

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

总复杂度为 \(O(\frac{q}{B}(m+B^2\log n))=O(\frac{qm}{B}+qB\log n)\),根据均值不等式可以得到 \(B\)\(\sqrt{m\log n}\) 最优。

代码:

#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 @ 2025-03-03 20:28  incra  阅读(13)  评论(0)    收藏  举报