社区讨论

Only AC on HACK 0pts 求助,码风良好,玄双关

P2486[SDOI2011] 染色参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mk8f370w
此快照首次捕获于
2026/01/10 22:45
上个月
此快照最后确认于
2026/01/14 15:30
上个月
查看原帖
CPP
#include <cstdio>
#include <vector>
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MAXSZ = 1 << 20;
char ch, buf[MAXSZ], *p1, *p2;
#define ge() (p1 == p2 && (p2 = buf + fread(p1 = buf, 1, MAXSZ, stdin), p1 == p2) ? EOF : *p1++)
#define end() putchar('\n')
#define space() putchar(' ')
#define mset(a, b) memset(a, b, sizeof a)
template <typename T_T>
inline void read(T_T &x) {
	x = 0;
	bool flag = false;
	
	while (ch < '0' || '9' < ch) ch = ge(), flag |= (ch == '-');
	while ('0' <= ch && ch <= '9') {
		x = x * 10 + (ch ^ 48);
		ch = ge();
	}
	
	x = flag ? -x : x;
}
inline void cread(char &x) {
	while (ch != 'Q' && ch != 'C') ch = ge();
	x = ch;
}
template <typename T_T>
inline void write(T_T x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	
	if (x > 9) write(x / 10);
	putchar(x % 10 | 48);
}
template <typename T_T>
inline T_T min(T_T x, T_T y) { return x < y ? x : y; }
template <typename T_T>
inline T_T max(T_T x, T_T y) { return x > y ? x : y; }

const int N = 1e5 + 5, Root = 1;

int opl, opr, opval;
std::vector <int> tr[N];
int n, T, initial[N], first[N], dfn[N], pdfn, fa[N], depth[N], sz[N], sheavy[N], heavy[N], Rc, Lc;
struct SGT {
	SGT *son[2];
	int chead, ctail, ans, lazy;
}*null, *root;
void newNode(SGT *&u) {u = new SGT; *u = {{null, null}, -1, -1, 0, -1};}

void CalcLazy(SGT *u, int val) {
	if (val == -1) return ;
	if (u == null) return ;
	
	u -> ans = 1, u -> chead = val, u -> ctail = val;
	u -> lazy = val;
}
void PushDown(SGT *u) {
	CalcLazy(u -> son[0], u -> lazy);
	CalcLazy(u -> son[1], u -> lazy);
	
	u -> lazy = -1;
}
void PushUp(SGT *u) {
	if (u -> son[0] == null || u -> son[1] == null) return ;

	u -> chead = u -> son[0] -> chead;
	u -> ctail = u -> son[1] -> ctail;
	u -> ans = u -> son[0] -> ans + u -> son[1] -> ans;

	if (u -> son[0] -> ctail == u -> son[1] -> chead) -- u -> ans;
}
void modify(SGT *&u, int l, int r) {
    // printf("Modify ---> target:[%d,%d] Now:[%d,%d] Val:[%d,%d]\n", opl, opr, l, r, u -> chead, u -> ctail);
	if (opl <= l && r <= opr) {CalcLazy(u, opval); return ;}
	
	PushDown(u);
	
	int mid = l + r >> 1;
	if (opl <= mid) modify(u -> son[0], l, mid);
	if (mid < opr) modify(u -> son[1], mid + 1, r);
	
	PushUp(u);
}
int query(SGT *&u, int l, int r) {
    // printf("Query --> target:[%d,%d] Now:[%d,%d] Val:[%d,%d,%d]\n", opl, opr, l, r, u -> chead, u -> ctail, u -> ans);
	if (l == opl) Lc = u -> chead;
	if (r == opr) Rc = u -> ctail;
	if (opl <= l && r <= opr) return u -> ans;
	
	PushDown(u);
	
	int mid = l + r >> 1;
	int res = 0;
	
	if (opr <= mid) res = query(u -> son[0], l, mid);
	else if (mid < opl) res = query(u -> son[1], mid + 1, r);
	else {
		res = query(u -> son[0], l, mid) + query(u -> son[1], mid + 1, r);
		if (u -> son[0] -> ctail == u -> son[1] -> chead) -- res;
	}
	
	PushUp(u);
	return res;
}

// void Print(SGT *now, int l, int r) {
// 	if (now == null) return ;

// 	PushDown(now);
// 	int mid = l + r >> 1;
// 	Print(now -> son[0], l, mid);
// 	Print(now -> son[1], mid + 1, r);
// 	PushUp(now);

// 	printf("section:[%d,%d] head:%d tail:%d Ans:%d\n", l, r, now -> chead, now -> ctail, now -> ans);
// }

void dfs1(int u) {
	sz[u] = 0;
	depth[u] = depth[fa[u]] + 1;
	
	for (auto v : tr[u]) {
		if (v == fa[u]) continue ;
		
		fa[v] = u;
		dfs1(v);
		sz[u] += sz[v];
		if (sz[v] > sz[heavy[u]]) 
			heavy[u] = v;
	}
	
	++ sz[u];
}
void dfs2(int u) {
	dfn[u] = ++ pdfn;
	
	if (heavy[u]) {
		first[heavy[u]] = first[u];
		dfs2(heavy[u]);
	}
	
//	printf("%d %d %d\n", u, first[u], heavy[u]);

	sheavy[u] = sheavy[heavy[u]] + 1;
	for (auto v : tr[u]) {
		if (v == fa[u] || v == heavy[u]) continue ;

		first[v] = v;
		dfs2(v);
	}
}

void FindPath(int u, int v, int type) {
	if (type == 1) read(opval);

	int clast1 = -1, clast2 = -1, ans = 0;
	for (; first[u] != first[v]; u = fa[first[u]]) {
		if (depth[first[u]] < depth[first[v]]) std::swap(u, v), std::swap(clast1, clast2);
		
		opl = dfn[first[u]], opr = dfn[u];
		if (type == 2) {
			ans += query(root, 1, n);

			if (clast1 == Lc) -- ans;
			clast1 = Rc;
		}
		else modify(root, 1, n);
	}

	if (depth[u] > depth[v]) std::swap(u, v), std::swap(clast1, clast2);
	
	opl = dfn[u], opr = dfn[v];
	if (type == 2) {
		ans += query(root, 1, n);

		if (clast1 == Rc) -- ans;
		if (clast2 == Lc) -- ans;
		write(ans);
	}
	else modify(root, 1, n);
}
void build(SGT *&u, int l, int r) {
    newNode(u);
    if (l == r) return ;

    int mid = l + r >> 1;
    build(u -> son[0], l, mid);
    build(u -> son[1], mid + 1, r);

    PushUp(u);
}

int main() {
	// freopen("Ryan.in", "r", stdin);
	// freopen("Ryan.out", "w", stdout);
	
	null = new SGT;
	*null = {{null, null}, -1, -1, 0, -1};
	root = null;
	
	read(n), read(T); build(root, 1, n);
	for (int i = 1; i <= n; i++) read(initial[i]);
	
	for (int i = 1; i < n; i++) {
		int u, v; read(u), read(v);
		
		tr[u].emplace_back(v);
		tr[v].emplace_back(u);
	}
	
	dfs1(Root);
	first[Root] = Root;
	dfs2(Root);

    for (int i = 1; i <= n; i++) {
        opl = dfn[i], opr = dfn[i]; opval = initial[i];
        modify(root, 1, n);
    }

	// for (int i = 1; i <= n; i++)
	// 	printf("%d %d\n", dfn[i], initial[i]);
	// Print(root, 1, n);

	while (T --) {
		char ch; cread(ch);
		int u, v; read(u), read(v);
		// Print(root, 1, n), end();

		if (ch == 'Q') FindPath(u, v, 2), end();
		else FindPath(u, v, 1);
	}
	
	// fclose(stdin), fclose(stdout);
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...