【SPOJ】375. Query on a tree(树链剖分)

http://www.spoj.com/problems/QTREE/

这是按边分类的。

调试调到吐,对拍都查不出来,后来改了下造数据的,拍出来了。囧啊啊啊啊啊啊

时间都花在调试上了,打hld只用了半小时啊囧。

第一次打边分类真没注意一个地方。

就是当fx==fy后,没有判断x==y,然后这是边分类,获得的是父亲的下标,果断错。。

囧,一定要记住这个错误。

#include <cstring>

#include <cstdio>

#include <iostream>

using namespace std;

#define lc x<<1

#define rc x<<1|1

#define lson l, m, lc

#define rson m+1, r, rc

#define MID (l+r)>>1

#define read(x) x=getint()

#define dbg(x) cout << #x << "=" << x << endl

inline const int max(const int& a, const int& b) { return a>b?a:b; }

inline int getint() { char c; int ret=0, k=1; for(c=getchar(); c<'0' || c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0' && c<='9'; c=getchar()) ret=ret*10+c-'0'; return k*ret; }



const int N=50010, oo=~0u>>1;

struct Ed { int u, v, w; }e[N];

int ihead[N], inext[N<<1], to[N<<1], cnt;

int fa[N], sz[N], son[N], top[N], dep[N], id[N], mx[N*5], num[N], tot, L, R, key, n;



inline void pushup(const int &x) { mx[x]=max(mx[lc], mx[rc]); }

void build(const int &l, const int &r, const int &x) {

	if(l==r) { mx[x]=num[l]; return; }

	int m=MID;

	build(lson); build(rson);

	pushup(x); 

}

void update(const int &l, const int &r, const int &x) {

	if(l==r) { mx[x]=key; return; }

	int m=MID;

	if(L<=m) update(lson); if(m<R) update(rson); pushup(x);

}

int getmax(const int &l, const int &r, const int &x) {

	if(L<=l && r<=R) return mx[x];

	int m=MID, ret=oo+1;

	if(L<=m) ret=max(ret, getmax(lson)); if(m<R) ret=max(ret, getmax(rson)); return ret;

}

void dfs1(const int &u) {

	sz[u]=1; int v;

	for(int i=ihead[u]; i; i=inext[i]) if(fa[u]!=(v=to[i])) {

		fa[v]=u; dep[v]=dep[u]+1;

		dfs1(v);

		sz[u]+=sz[v];

		if(sz[v]>sz[son[u]]) son[u]=v;

	}

}

void dfs2(const int &u, const int &tp) {

	id[u]=++tot; top[u]=tp;

	if(son[u]) dfs2(son[u], tp);

	for(int i=ihead[u]; i; i=inext[i]) if(fa[u]!=to[i] && to[i]!=son[u]) dfs2(to[i], to[i]);

}

inline int getmax(int x, int y) {

	int fx=top[x], fy=top[y], ret=oo+1;

	while(fx!=fy) {

		if(dep[fx]<dep[fy]) { swap(x, y); swap(fx, fy); }

		L=id[fx]; R=id[x];

		ret=max(ret, getmax(2, n, 1));

		x=fa[fx]; fx=top[x];

	}

	if(dep[x]>dep[y]) swap(x, y);

	if(x!=y) L=id[x]+1; R=id[y]; //这里,如果不特判的话,L会>R,然后线段树那里果断死循环

	return max(ret, getmax(2, n, 1));

}

inline void add(const int &u, const int &v) {

	inext[++cnt]=ihead[u]; ihead[u]=cnt; to[cnt]=v;

	inext[++cnt]=ihead[v]; ihead[v]=cnt; to[cnt]=u;

}

int main() {

	int c=getint(), a, b; char ch;

	while(c--) {

		read(n);

		tot=cnt=0;

		memset(ihead, 0, sizeof(int)*(n+10));

		memset(fa, 0, sizeof(int)*(n+10));

		memset(son, 0, sizeof(int)*(n+10));

		for(int i=1; i<n; ++i) {

			read(e[i].u); read(e[i].v); read(e[i].w);

			add(e[i].u, e[i].v);

		}

		dfs1(1); dfs2(1, 1);

		for(int i=1; i<n; ++i) {

			if(dep[e[i].u]>dep[e[i].v]) swap(e[i].u, e[i].v);

			num[id[e[i].v]]=e[i].w;

		}

		build(2, n, 1);

		for(ch=getchar(); ch<'A' || ch>'Z'; ch=getchar());

		while(ch!='D') {

			read(a); read(b);

			if(ch=='C') { key=b; L=R=id[e[a].v]; update(2, n, 1); }

			else printf("%d\n", getmax(a, b));

			for(ch=getchar(); ch<'A' || ch>'Z'; ch=getchar());

		}

	}

	return 0;	

}

 

 


 

 

You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.

We will ask you to perfrom some instructions of the following form:

  • CHANGE i ti : change the cost of the i-th edge to ti
    or
  • QUERY a b : ask for the maximum edge cost on the path from node a to node b

Input

The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.

For each test case:

  • In the first line there is an integer N (N <= 10000),
  • In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000),
  • The next lines contain instructions "CHANGE i ti" or "QUERY a b",
  • The end of each test case is signified by the string "DONE".

There is one blank line between successive tests.

Output

For each "QUERY" operation, write one integer representing its result.

Example

Input:

1



3

1 2 1

2 3 2

QUERY 1 2

CHANGE 1 3

QUERY 1 2

DONE



Output:

1

3

你可能感兴趣的:(query)