关于树剖+珂朵莉树的代码个人实现问题
查看原帖
关于树剖+珂朵莉树的代码个人实现问题
126765
cyslngsul楼主2022/7/17 21:02
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1000000007, N = 101000;
struct Q{
	int l, r;
	mutable int v;
	Q(int l = 0, int r = 0, int v = 0):l(l), r(r), v(v){}
	bool operator< ( const Q& a) const { return l < a.l; }
};
set<Q> st;
int n, m, seed, vmax, nums[N], temp;
set<Q>::iterator split( int pos ){
	auto i = st.lower_bound(Q(pos));
	if ( i != st.end() && i -> l == pos )
		return i;
	--i;
	if ( i -> r < pos )
		return st.end();
	int l = i -> l, r = i -> r, v = i -> v;
	st.erase(i);
	st.insert(Q(l, pos-1, v));
	return st.insert(Q(pos, r, v)).first;
}
void assign( int l, int r, int c ){
	auto ir = split(r+1), il = split(l);
	st.erase(il, ir);
	st.insert(Q(l, r, c));
}
int query( int l, int r, int& lst ){
	auto ir = split(r+1), il = split(l);
	int res = 0;
	for ( --ir; ; --ir ) {
		if ( ir -> v != lst )
			lst = ir -> v, ++res;
		if ( il == ir )
			break;
	}
	return res;
}
struct EGDE {
	int v, nxt;
}edge[N*2];
int cnt, head[N], fa[N], depth[N], sz[N], hson[N], tot, dfnin[N], dfnout[N], top[N], ord[N];
void add_edge( int u, int v ) {
	edge[++cnt].v = v;
	edge[cnt].nxt = head[u];
	head[u] = cnt;
}
int root;


void DFS1( int u, int f ){
	sz[u] = 1;
	fa[u] = f;
	depth[u] = depth[f] + 1;
	for ( int i = head[u]; i; i = edge[i].nxt ) {
		int v = edge[i].v;
		if ( v == f )
			continue;
		DFS1(v, u);
		sz[u] += sz[v];
		if ( sz[hson[u]] < sz[v] )
			hson[u] = v;
	}
}
void DFS2( int u, int ct ){
	top[u] = ct;
	dfnin[u] = ++tot;
	ord[tot] = nums[u];
	if ( hson[u] )
		DFS2(hson[u], ct);
	for ( int i = head[u]; i; i = edge[i].nxt ) {
		int v = edge[i].v;
		if ( v == fa[u] || v == hson[u] )
			continue;
		DFS2(v, v);
	}
	dfnout[u] = tot;
}
int path( int u, int v, int w = 0 ){
	int res = 0, lu = 0, lv = 0, ched = 0;//lb for v, la for u
	for ( ; top[u] != top[v]; u = fa[top[u]] ) {
		if ( depth[top[u]] < depth[top[v]] )
			swap(u, v), ched ^= 1;
		if ( w )
			assign(dfnin[top[u]], dfnin[u], w);
		else
			res += ched ? query(dfnin[top[u]], dfnin[u], lv) : query(dfnin[top[u]], dfnin[u], lu);
	}
	if ( u != v ) {
		if ( depth[u] < depth[v] )
			swap(u, v), ched ^= 1;//u is deeper than v
		if ( w )
			assign(dfnin[v], dfnin[u], w);
		else
			res += ched ? query(dfnin[v], dfnin[u], lv) : query(dfnin[v], dfnin[u], lu);
	}
	return res - (lu==lv);
}

signed main() {
	scanf("%lld%lld", &n, &m);
	for ( int i = 1; i <= n; ++i )
		scanf("%lld", &nums[i]);
	for ( int i = 1, u, v; i < n; ++i ) {
		scanf("%lld%lld", &u, &v);
		add_edge(u, v);
		add_edge(v, u);
	}
	DFS1(1, 0);
	DFS2(1, 1);
	for ( int i = 1; i <= n; ++i )
		st.insert(Q(i, i, ord[i]));
	char str[2];
	for ( int i = 1, a, b, c; i <= m; ++i ) {
		scanf("%s%lld%lld", str, &a, &b);
		if ( str[0] == 'C' ) {
			scanf("%lld", &c);
			path(a, b, c);
		} else
			printf("%lld\n", path(a, b));
	}
	return 0;
}

25分求调。基本可以确定不是树剖或者珂朵莉树的问题……

2022/7/17 21:02
加载中...