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:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3