HDU 5002 Tree

5177 단어 HDU데이터 구조
제목:
나무 한 그루  삭제 변 추가, 경로 가중치 추가, 경로 가중치 변경, 경로 에서 두 번 째 로 큰 숫자 와 개 수 를 구 하 는 것 을 지원 합 니 다.
생각:
엘 시 티 의 두 번 째 문제.  제목 의 뜻 은 이미 기능 을 모두 알려 주 었 다.  비교적 나체로
주의해 야 할 것 은 가중치 와 값 변경 두 작업 의 태그 아래 문제 입 니 다.  먼저 다운 하여 값 을 바 꿔 야 한다.  더 다운 플러스
경로 에 대한 조작 은 mroot 를 통 해 트 리 의 형 태 를 바 꾸 고 access 에서 경 로 를 꺼 내 는 것 이 편리 합 니 다.  나 전편 처럼 lca 하지 마.
코드:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define N 100010
#define L(x) (ch[x][0])
#define R(x) (ch[x][1])
#define inf -2147483640

int ch[N][2], pre[N], rev[N], me[N];
int cov[N], add[N], size[N], max1[N], num1[N], max2[N], num2[N];
bool rt[N];

struct helper {
	int val, num;
	bool operator ff.val;
	}
} hel[10];

void Update_COV(int u, int d) {
	if (!u)
		return;
	me[u] = d;
	cov[u] = d;
	add[u] = inf;
	max1[u] = d;
	num1[u] = size[u];
	max2[u] = inf;
	num2[u] = 0;
}

void Update_Add(int u, int d) {
	if (!u)
		return;
	me[u] += d;
	if (add[u] != inf)
		add[u] += d;
	else
		add[u] = d;
	max1[u] += d;
	if (max2[u] != inf)
		max2[u] += d;
}

void Update_Rev(int u) {
	if (!u)
		return;
	swap(L(u), R(u));
	rev[u] ^= 1;
}

void down(int u) {
	if (rev[u]) {
		Update_Rev(L(u));
		Update_Rev(R(u));
		rev[u] = 0;
	}
	if (cov[u] != inf) {
		Update_COV(L(u), cov[u]);
		Update_COV(R(u), cov[u]);
		cov[u] = inf;
	}
	if (add[u] != inf) {
		Update_Add(L(u), add[u]);
		Update_Add(R(u), add[u]);
		add[u] = inf;
	}
}

void up(int u) {
	size[u] = size[L(u)] + size[R(u)] + 1;
	hel[0].val = max1[L(u)];
	hel[0].num = num1[L(u)];
	hel[1].val = max2[L(u)];
	hel[1].num = num2[L(u)];
	hel[2].val = max1[R(u)];
	hel[2].num = num1[R(u)];
	hel[3].val = max2[R(u)];
	hel[3].num = num2[R(u)];
	hel[4].val = me[u];
	hel[4].num = 1;
	sort(hel, hel + 5);
	int i;
	for (i = 1; i < 5; i++) {
		if (hel[i].val != hel[i - 1].val)
			break;
	}
	max1[u] = hel[0].val;
	max2[u] = hel[i].val;
	num1[u] = num2[u] = 0;
	for (i = 0; i < 5; i++) {
		if (hel[i].val == max1[u])
			num1[u] += hel[i].num;
		else if (hel[i].val == max2[u])
			num2[u] += hel[i].num;
	}
}

//Rotate P Splay     
void Rotate(int x) {
	int y = pre[x], kind = ch[y][1] == x;
	ch[y][kind] = ch[x][!kind];
	pre[ch[y][kind]] = y;
	pre[x] = pre[y];
	pre[y] = x;
	ch[x][!kind] = y;
	if (rt[y])
		rt[y] = false, rt[x] = true;
	else
		ch[pre[x]][ch[pre[x]][1] == y] = x;
	up(y);
}

//P    splay    u                
void P(int u) {
	if (!rt[u])
		P(pre[u]);
	down(u);
}

void Splay(int u) {
	P(u);
	while (!rt[u]) {
		int fa = pre[u], ffa = pre[fa];
		if (rt[fa])
			Rotate(u);
		else if ((R(ffa) == fa) == (R(fa) == u))
			Rotate(fa), Rotate(u);
		else
			Rotate(u), Rotate(u);
	}
	up(u);
}

// root u       
int Access(int u) {
	int v = 0;
	for (; u; u = pre[v = u]) {
		Splay(u);
		rt[R(u)] = true, rt[R(u) = v] = false;
		up(u);
	}
	return v;
}

// u         
void mroot(int u) {
	Access(u);
	Splay(u);
	Update_Rev(u);
}

//       u  v 
void link(int u, int v) {
	mroot(u);
	pre[u] = v;
}

//u-v   
void cut(int u, int v) {
	mroot(u);
	Access(u);
	Splay(v);
	pre[L(v)] = pre[v];
	pre[v] = 0;
	rt[L(v)] = true;
	L(v) = 0;
	up(v);
}

//u-v      w
void COV(int u, int v, int w) {
	mroot(u);
	Access(v);
	Splay(v);
	Update_COV(v, w);
}

//u-v  +w
void ADD(int u, int v, int w) {
	mroot(u);
	Access(v);
	Splay(v);
	Update_Add(v, w);
}

//u-v     
void query(int u, int v) {
	mroot(u);
	Access(v);
	Splay(v);
	if (max2[v] != inf)
		printf("%d %d
", max2[v], num2[v]); else printf("ALL SAME
"); } struct edge { int v, next; } ed[N * 2]; int head[N], tot; void addedge(int u, int v) { ed[tot].v = v; ed[tot].next = head[u]; head[u] = tot++; } // dfs pre LCT void dfs(int u) { for (int i = head[u]; ~i; i = ed[i].next) { int v = ed[i].v; if (pre[v] != 0) continue; pre[v] = u; dfs(v); } } int main() { int T, t, n, m, i, op, u, v, x, y, w; max1[0] = max2[0] = inf; rt[0] = true; scanf("%d", &T); for (t = 1; t <= T; t++) { scanf("%d%d", &n, &m); for (i = 1; i <= n; i++) { scanf("%d", &me[i]); max1[i] = me[i]; max2[i] = inf; num1[i] = 1; num2[i] = 0; size[i] = 1; add[i] = cov[i] = inf; L(i) = R(i) = pre[i] = rev[i] = 0; rt[i] = true; } tot = 0; memset(head, -1, sizeof(head)); for (i = 1; i < n; i++) { scanf("%d%d", &u, &v); addedge(u, v); addedge(v, u); } pre[1] = -1; dfs(1); pre[1] = 0; printf("Case #%d:
", t); while (m--) { scanf("%d", &op); if (op == 1) { scanf("%d%d%d%d", &u, &v, &x, &y); cut(u, v); link(x, y); } else if (op == 2) { scanf("%d%d%d", &u, &v, &w); COV(u, v, w); } else if (op == 3) { scanf("%d%d%d", &u, &v, &w); ADD(u, v, w); } else { scanf("%d%d", &u, &v); query(u, v); } } } return 0; }

좋은 웹페이지 즐겨찾기