萌新求调
查看原帖
萌新求调
503792
Svemit楼主2024/11/28 15:49

rt

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;

int n, m;
struct Seg {
	int l, r, a, b;
	Seg() {}
	Seg(int _l, int _r, int _a, int _b) { l = _l, r = _r, a = _a, b = _b; }
	bool operator <(const Seg &t) const { return b < t.b; }
} seg[N];
vector<int> vs;
int fa[N];

struct pii {
	int fi, se;
	pii() {}
	pii(int _fi, int _se) { fi = _fi, se = _se; } 
	bool operator <(const pii &t) const { return fi < t.fi; }
	bool operator ==(const pii &t) const { return se == t.se; }
	bool operator !=(const pii &t) const { return !(*this == t); }
} E[N];

struct Info {
	pii minv1, minv2;
	Info () { minv1 = pii(-1e9, -1e9), minv2 = pii(-1e9, -1e9); }
	Info (pii _minv1, pii _minv2) { minv1 = _minv1, minv2 = _minv2; }
} les[N], gre[N];

struct Tag {
	Info t;
	Tag () { clear(); }
	Tag (Info _t) { t = _t; }
	bool empty() { return t.minv1 == pii(-1e9, -1e9) && t.minv2 == pii(-1e9, -1e9); }
	void clear() { t = Info(pii(-1e9, -1e9), pii(-1e9, -1e9)); }
};

Info operator +(Info x, Info y) {
	Info res;
	static vector<pii> vec;
	vec.clear();
	vec.push_back(x.minv1), vec.push_back(x.minv2);
	vec.push_back(y.minv1), vec.push_back(y.minv2);
	sort(vec.begin(), vec.end());
	for (auto i : vec) {
		if (i.se == -1e9) continue;
		if (res.minv1.fi == -1e9) res.minv1 = i;
		else if (res.minv2.fi == -1e9 && i.se != res.minv1.se) res.minv2 = i;
	}
	return res;
}

Info operator +(Info x, Tag y) {
	return x + y.t;
}

Tag operator +(Tag x, Tag y) {
	x.t = x.t + y.t;
	return x;
}

struct Segment_Tree {
	struct Node {
		int l, r;
		Info val;
		Tag tag;

		void apply(Tag v) {
			val = val + v, tag = tag + v;
		} 

		#define l(x) tr[x].l
		#define r(x) tr[x].r
		#define val(x) tr[x].val
		#define tag(x) tr[x].tag
	} tr[N * 4];

	void pushdown(int x) {
		if (tag(x).empty()) return;
		tr[x * 2].apply(tag(x)), tr[x * 2 + 1].apply(tag(x));
		tag(x).clear();
	}

	void build(int l, int r, int x) {
		tr[x] = {l, r, Info(pii(-1e9, -1e9), pii(-1e9, -1e9))};
		tag(x).clear();
		if (l == r) return;
		int mid = (l + r) / 2;
		build(l, mid, x * 2), build(mid + 1, r, x * 2 + 1);
	}

	void update(int l, int r, Tag v, int x = 1) {
		if (l <= l(x) && r(x) <= r) {
			tr[x].apply(v);
			return;
		}
		pushdown(x);
		int mid = (l(x) + r(x)) / 2;
		if (l <= mid) update(l, r, v, x * 2);
		if (r > mid) update(l, r, v, x * 2 + 1);
		val(x) = val(x * 2) + val(x * 2 + 1);
	}

	Info query(int l, int r, int x = 1) {
		if (l <= l(x) && r(x) <= r) return val(x);
		pushdown(x);
		int mid = (l(x) + r(x)) / 2;
		if (r <= mid) return query(l, r, x * 2);
		else if (l > mid) return query(l, r, x * 2 + 1);
		else return query(l, r, x * 2) + query(l, r, x * 2 + 1);
	}
} SegT;

void init() {
	vs.clear();
	for (int i = 1; i <= n; i ++) fa[i] = i;
}
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void merge(int x, int y) { fa[find(x)] = find(y); }
int get(int x) { return lower_bound(vs.begin(), vs.end(), x) - vs.begin() + 1; }

void solve() {
	cin >> n;
	init();
	for (int i = 1; i <= n; i ++) {
		int l, r, a, b;
		cin >> l >> r >> a >> b;
		seg[i] = Seg(l, r, a, b);
		vs.push_back(l), vs.push_back(r);
	}
	sort(seg + 1, seg + 1 + n);
	sort(vs.begin(), vs.end());
	vs.erase(unique(vs.begin(), vs.end()), vs.end());
	m = vs.size();
	for (int i = 1; i <= n; i ++) seg[i].l = get(seg[i].l), seg[i].r = get(seg[i].r);
	ll ans = 0;
	int cnt = n;
	while (cnt > 1) {
		SegT.build(1, m, 1);
		int j = 1;
		for (int i = 1; i <= n; i ++) {
			int l = seg[i].l, r = seg[i].r;
			while (j <= n && seg[j].b == seg[i].b) SegT.update(seg[j].l, seg[j].r, Tag(Info(pii(seg[j].a - seg[j].b, find(j)), pii(-1e9, -1e9)))), j ++;
			les[i] = SegT.query(l, r);
		}
		SegT.build(1, m, 1);
		j = n;
		for (int i = n; i >= 1; i --) {
			int l = seg[i].l, r = seg[i].r;
			while (j >= 1 && seg[j].b == seg[i].b) SegT.update(seg[j].l, seg[j].r, Tag(Info(pii(seg[j].a + seg[j].b, find(j)), pii(-1e9, -1e9)))), j --;
			gre[i] = SegT.query(l, r);
		}
		for (int i = 1; i <= n; i ++) {
			E[i] = pii(-1e9, -1e9);
			int a = seg[i].a, b = seg[i].b;
			pii t;
			if (les[i].minv1.se == find(i)) t = les[i].minv2;
			else t = les[i].minv1;
			if (t.se != -1e9) E[i] = pii(a + b + t.fi, t.se);
			if (gre[i].minv1.se == find(i)) t = gre[i].minv2;
			else t = gre[i].minv1;
			if (t.se != -1e9) {
				if (a - b + t.fi < E[i].fi) E[i] = pii(a - b + t.fi, t.se);
			}
		}
		bool ok = false;
		for (int i = 1; i <= n; i ++) {
			int j = E[i].se, w = E[i].fi;
			if (j == -1e9) continue;
			if (find(i) == find(j)) continue;
			ok = true;
			ans += w;
			merge(i, j);
		}
		if (!ok) break;
		cnt = 0;
		for (int i = 1; i <= n; i ++) cnt += (find(i) == i);
	}
	if (cnt > 1) ans = -1;
	cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    int t;
    cin >> t;

    while (t --) {
    	solve();
    }

    return 0;
}
2024/11/28 15:49
加载中...