LCT 做法 10pts 求助
查看原帖
LCT 做法 10pts 求助
727888
LCATreap楼主2022/6/15 17:20

rt,几乎对着题解调,都是很多行之后才错,已过大样例,请问是哪里写挂了吗?

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int N = 4e5 + 10;
struct node {
	int ch[2], fa;
	ll val, ans;
}spl[N];
#define ls(x) (spl[x].ch[0])
#define rs(x) (spl[x].ch[1])
#define fa(x) (spl[x].fa)
#define val(x) (spl[x].val)
#define ans(x) (spl[x].ans)
#define indnt(x) (x == rs(fa(x)))
#define ntrt(x) (x == ls(fa(x)) || x == rs(fa(x)))
#define upd(x) (ans(x) = ans(ls(x)) + ans(rs(x)) + val(x))
inline void rtt(int x) {
	int f = fa(x), ff = fa(f), d = indnt(x);
	spl[f].ch[d] = spl[x].ch[d ^ 1];
	fa(spl[x].ch[d ^ 1]) = f;
	fa(x) = ff;
	if (ntrt(f))spl[ff].ch[indnt(f)] = x;
	spl[x].ch[d ^ 1] = f; fa(f) = x;
	upd(f), upd(x);
}
inline void splaying(int x) {
	int f, ff;
	while (ntrt(x)) {
		f = fa(x), ff = fa(f);
		if (ntrt(f))indnt(x) ^ indnt(f) ? rtt(x) : rtt(f);
		rtt(x);
	}
}
inline int findrt(int x) {
	splaying(x);
	while (ls(x))x = ls(x);
	splaying(x);
	return x;
}
inline int findlf(int x){
	splaying(x);
	while (rs(x))x = rs(x);
	splaying(x);
	return x;
}
inline void link(int x, int y) {
	if (findrt(x) == findrt(y))return;
	x = findrt(x), y = findlf(y);
	fa(x) = y; rs(y) = x;
}
inline void cut(int x) {
	splaying(x);
	ls(fa(x)) = 0;
	ls(x) = 0; 
}
ll getsum(ll x){
	splaying(x);
	return ans(ls(x)) + val(x);
}
inline ll split(int x, int y) {
	if(findrt(x) != findrt(y))return -1;
	ll xsum = getsum(x), ysum = getsum(y);
	if(xsum > ysum)return xsum - ysum + val(y);
	else return ysum - xsum + val(x);
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(); cout.tie();
	int n, m, x, y;  char q;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)cin >> spl[i].val;
	while(m--){
		cin >> q;
		if(q == 'M')cin >> x >> y, link(x, y);
		else if(q == 'D')cin >> x, cut(x);
		else cin >> x >> y, cout << split(x, y) << endl;
	}
	return 0;
}
2022/6/15 17:20
加载中...