[BZOJ 2243] [SDOI 2011] 染色 【树链剖分】

题目链接:BZOJ - 2243

 

题目分析

树链剖分...写了200+行...Debug了整整一天+...

静态读代码读了 5 遍 ,没发现错误,自己做小数据也过了。

提交之后全 WA 。

————————————— 杯具的分割线 —————————————————

然后看了别人代码。。然后发现。。

我写线段树区间修改竟然没打标记!!!!直接就修改上了!!!最裸的线段树都不会写了!!!

Warning!Warning!Warning!

 

代码

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

const int MaxN = 100000 + 5;

int n, m, Index;
int Father[MaxN], Son[MaxN], Depth[MaxN], Top[MaxN], A[MaxN], Size[MaxN], Pos[MaxN];
int Color[MaxN];

struct Edge
{
	int v;
	Edge *Next;
} E[MaxN * 2], *P = E, *Point[MaxN];

inline void AddEdge(int x, int y) {
	++P; P -> v = y;
	P -> Next = Point[x]; Point[x] = P;
}

int DFS_1(int x, int Dep, int Fa) {
	Depth[x] = Dep; 
	Father[x] = Fa;
	Size[x] = 1;
	int SonSize, MaxSonSize;
	SonSize = MaxSonSize = 0;
	for (Edge *j = Point[x]; j; j = j -> Next) {
		if (j -> v == Fa) continue;
		SonSize = DFS_1(j -> v, Dep + 1, x);
		if (SonSize > MaxSonSize) {
			Son[x] = j -> v;
			MaxSonSize = SonSize;
		}
		Size[x] += SonSize;
	}
	return Size[x];
}

void DFS_2(int x) {
	if (x == 0) return;
	if (x == Son[Father[x]]) Top[x] = Top[Father[x]];
	else Top[x] = x;
	Pos[x] = ++Index;
	Color[Pos[x]] = A[x];
	DFS_2(Son[x]);
	for (Edge *j = Point[x]; j; j = j -> Next) {
		if (j -> v == Father[x] || j -> v == Son[x]) continue;
		DFS_2(j -> v);
	}
}

struct ES 
{
	int Lx, Rx, Tx;
	ES() {}
	ES(int a, int b, int c) {
		Lx = a; Rx = b; Tx = c;
	}
} T[MaxN * 4], D[MaxN * 4];

ES Plus(ES e1, ES e2) {
	ES ret;
	if (e1.Tx == 0) return e2;
	if (e2.Tx == 0) return e1;
	ret = ES(e1.Lx, e2.Rx, e1.Tx + e2.Tx);
	if (e1.Rx == e2.Lx) --ret.Tx;
	return ret;
}

inline void Update(int x) {
	T[x] = Plus(T[x << 1], T[x << 1 | 1]);
}

void Plant_Tree(int x, int s, int t) {
	if (s == t) {
		T[x] = ES(Color[s], Color[s], 1);
		D[x] = ES(0, 0, 0);
		return;
	}
	int m = (s + t) >> 1;
	Plant_Tree(x << 1, s, m);
	Plant_Tree(x << 1 | 1, m + 1, t);
	Update(x);
}

inline void Paint(int x, ES Dlt) {
	T[x] = Dlt;
	D[x] = Dlt;
}

inline void PushDown(int x) {
	if (D[x].Tx == 0) return;
	Paint(x << 1, D[x]);
	Paint(x << 1 | 1, D[x]);
	D[x] = ES(0, 0, 0);
}

void Change_Tree(int x, int s, int t, int l, int r, int Col) {
	if (l <= s && r >= t) {
		ES Temp = ES(Col, Col, 1);
		Paint(x, Temp);
		return;	
	}
	PushDown(x);
	int m = (s + t) >> 1;
	if (l <= m) Change_Tree(x << 1, s, m, l, r, Col);
	if (r >= m + 1) Change_Tree(x << 1 | 1, m + 1, t, l, r, Col);
	Update(x);
}

void Change_Color(int x, int y, int z) {
	int fx, fy;
	while (true) {
		fx = Top[x]; fy = Top[y];
		if (Depth[fx] < Depth[fy]) {
			swap(fx, fy);
			swap(x, y);
		}
		if (fx == fy) {
			if (Pos[x] < Pos[y]) Change_Tree(1, 1, n, Pos[x], Pos[y], z);
			else Change_Tree(1, 1, n, Pos[y], Pos[x], z);
			break;
		}
		else {
			Change_Tree(1, 1, n, Pos[fx], Pos[x], z);
			x = Father[fx];
		}
	}
}

ES Query_Tree(int x, int s, int t, int l, int r) {
	if (l <= s && r >= t) return T[x];
	PushDown(x);
	int m = (s + t) >> 1;
	ES ret = ES(0, 0, 0);
	if (l <= m) ret = Plus(ret, Query_Tree(x << 1, s, m, l, r)); 
	if (r >= m + 1) ret = Plus(ret, Query_Tree(x << 1 | 1, m + 1, t, l, r));
	return ret;
}

int Query(int x, int y) {
	int fx, fy, ret;
	ES Ansx, Ansy, Temp;
	Ansx = Ansy = ES(0, 0, 0);
	while (true) {
		fx = Top[x]; fy = Top[y];
		if (Depth[fx] < Depth[fy]) {
			swap(fx, fy);
			swap(x, y);
			swap(Ansx, Ansy);
		}
		if (fx == fy) {
			ret = Ansx.Tx + Ansy.Tx;
			if (Pos[x] < Pos[y]) {
				Temp = Query_Tree(1, 1, n, Pos[x], Pos[y]);
				ret += Temp.Tx;
				if (Ansy.Lx == Temp.Rx) --ret;
				if (Ansx.Lx == Temp.Lx) --ret;
			}
			else {
				Temp = Query_Tree(1, 1, n, Pos[y], Pos[x]);
				ret += Temp.Tx;
				if (Ansx.Lx == Temp.Rx) --ret;
				if (Ansy.Lx == Temp.Lx) --ret;
			}
			break;
		}
		else {
			Ansx = Plus(Query_Tree(1, 1, n, Pos[fx], Pos[x]), Ansx);
			x = Father[fx];
		}
	}
	return ret;
}

int main() 
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) scanf("%d", &A[i]);
	int a, b, c;
	for (int i = 1; i <= n - 1; ++i) {
		scanf("%d%d", &a, &b);
		AddEdge(a, b);
		AddEdge(b, a);
	}
	DFS_1(1, 0, 0);
	Index = 0;
	DFS_2(1);
	Plant_Tree(1, 1, n);
	char ch;
	int Ans;
	for (int i = 1; i <= m; ++i) {
		ch = '#';
		while (ch != 'C' && ch != 'Q') ch = getchar();
		if (ch == 'C') {
			scanf("%d%d%d", &a, &b, &c);
			Change_Color(a, b, c);
		}
		else {
			scanf("%d%d", &a, &b);
			Ans = Query(a, b);
			printf("%d\n", Ans);
		}
	}
	return 0;
}

  

posted @ 2015-01-15 10:11  JoeFan  阅读(237)  评论(0编辑  收藏  举报