LCT TLE 0pts 求调
查看原帖
LCT TLE 0pts 求调
1122732
yuguanchen2022楼主2025/7/29 11:31
#include<bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define lop(i, a, b) for (int i = (a); i < (b); i++)
#define dwn(i, a, b) for (int i = (a); i >= (b); i--)
#define pr pair<int, int>
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define iosfst ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
#define File(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
mt19937 Rnd(time(0));
namespace An{
const int N = 1e4 + 10;
int n, m, c, k;
map<pr, int> mp;
struct LCT{
	bool fx[N];
	int n, m, top, d[N];
	struct FHQ_Treap{
		int lsn, rsn, sum, pri, tag, fa, key, uni;
	} tr[N];
	void updateroot(int p) {
		tr[p].sum = max(tr[tr[p].lsn].sum, max(tr[tr[p].rsn].sum, tr[p].key));
		if (tr[p].lsn) tr[tr[p].lsn].fa = p;
		if (tr[p].rsn) tr[tr[p].rsn].fa = p;
		return;
	}
	bool isroot(int p) { return (tr[tr[p].fa].lsn != p && tr[tr[p].fa].rsn != p) || !tr[p].fa; }
	void pushdown(int p) {
		if (tr[p].tag) {
			swap(tr[p].lsn, tr[p].rsn);
			tr[tr[p].lsn].tag ^= 1, tr[tr[p].rsn].tag ^= 1;
			tr[p].tag = 0;
		}
		return;
	}
	int merge(int L, int R) {
		if (L == 0 || R == 0) return L + R;
		if (tr[L].pri < tr[R].pri) {
			pushdown(L);
			tr[L].rsn = merge(tr[L].rsn, R);
			updateroot(L);
			return L;
		}
		else {
			pushdown(R);
			tr[R].lsn = merge(L, tr[R].lsn);
			updateroot(R);
			return R;
		}
	}
	void split(int p, int &L, int &R){
		if(!top) return pushdown(p), L = p, R = tr[p].rsn, tr[p].rsn = 0, updateroot(p), void();
		bool d = fx[top--];
		d ^= tr[p].tag;
		if(d) R = p, split(tr[p].lsn, L, tr[p].lsn);
		else L = p,split(tr[p].rsn, tr[p].rsn, R);
		updateroot(p);
		return;
	}
	int findroot(int p) {
		top = 0;
		while (!isroot(p)) fx[++top] = (tr[tr[p].fa].lsn == p), p = tr[p].fa;
		return p;
	}
	int findminn(int p) {
		p = findroot(p), pushdown(p);
		while(tr[p].lsn) p = tr[p].lsn, pushdown(p);
		return p;
	}
	int access(int p) {
		int lst = 0;
		while(p) {
			int L, R;
			split(findroot(p), L, R);
			tr[findminn(lst)].uni = 0;
			lst = merge(L, lst);
			tr[findminn(R)].uni = p;
			p = tr[findminn(lst)].uni;
		}
		return lst;
	}
	int root(int p) { return findminn(access(p)); }
	void changeroot(int p) { tr[access(p)].tag ^= 1; }
	void link(int x, int y) { d[x]++, d[y]++, changeroot(x), tr[x].uni = y; }
	void cut(int x,int y) { d[x]--, d[y]--, changeroot(x), access(y), access(x), tr[y].uni = 0; }
	int query(int x,int y) { return tr[findroot(y)].sum; }
	void change(int x, int val) {
		changeroot(x);
		access(x);
		tr[x].key = val;
		updateroot(x);
		return;
	}
} T[11];
void lover() {
	cin >> n >> m >> c >> k;
	rep (i, 1, n) {
		int x; cin >> x;
		rep (j, 1, c) T[j].tr[i].key = T[j].tr[i].sum = x, T[j].tr[i].pri = Rnd();
	}
	rep (i, 1, m) {
		int u, v, w; cin >> u >> v >> w;
		w++;
		T[w].link(u, v);
		mp[mp(u, v)] = w, mp[mp(v, u)] = w;
	}
	rep (i, 1, k) {
		int op; cin >> op;
		if (op == 0) {
			int x, val; cin >> x >> val;
			rep (j, 1, c) T[j].change(x, val);
		}
		if (op == 1) {
			int u, v, w; cin >> u >> v >> w;
			w++;
			if (mp[mp(u, v)] == w) cout << "Success.\n";
			else if (!mp.count(mp(u, v))) cout << "No such edge.\n";
			else if (T[w].d[u] >= 2 || T[w].d[v] >= 2) { cout << "Error 1.\n"; }
			else {
				T[w].changeroot(u), T[w].access(v);
				if (T[w].findroot(u) == T[w].findroot(v)) { cout << "Error 2.\n"; }
				else {
					T[mp[mp(u, v)]].cut(u, v);
					mp[mp(u, v)] = w, mp[mp(v, u)] = w;
					T[w].link(u, v);
					cout << "Success.\n";
				}
			}
		}
		if (op == 2) {
			int cc, u, v; cin >> cc >> u >> v; 
			cc++;
			T[cc].changeroot(u), T[cc].access(v);
			if (T[cc].findroot(u) != T[cc].findroot(v)) cout << "-1\n";
			else cout << T[cc].query(u, v) << '\n';
		}
	}
	return;
}
}
signed main() {
//	iosfst;
    An::lover();
	return 0;
}

2025/7/29 11:31
加载中...