首页 > 代码库 > POJ 3237 Tree
POJ 3237 Tree
题目链接~~>
做题感悟:只要会线段树区间更新再加上剖分就搞定了。
解题思路:
主要注意怎样区间更新就ok了 。树链剖分就是树上的线段树。
代码:
#include<iostream> #include<sstream> #include<map> #include<cmath> #include<fstream> #include<queue> #include<vector> #include<sstream> #include<cstring> #include<cstdio> #include<stack> #include<bitset> #include<ctime> #include<string> #include<cctype> #include<iomanip> #include<algorithm> using namespace std ; #define INT __int64 #define L(x) (x * 2) #define R(x) (x * 2 + 1) const int INF = 0x3f3f3f3f ; const double esp = 0.0000000001 ; const double PI = acos(-1.0) ; const int mod = 1e9 + 7 ; const int MY = 1e7 + 5 ; const int MX = 10000 + 5 ; int n ,num ,idx ; int head[MX] ,dep[MX] ,top[MX] ,ti[MX] ,siz[MX] ,son[MX] ,father[MX] ; struct NODE { int u ,v ,w ; }e[MX] ; struct Edge { int v ,next ; }E[MX*2] ; void addedge(int u ,int v) { E[num].v = v ; E[num].next = head[u] ; head[u] = num++ ; E[num].v = u ; E[num].next = head[v] ; head[v] = num++ ; } void dfs_find(int u ,int fa) { dep[u] = dep[fa] + 1 ; siz[u] = 1 ; son[u] = 0 ; father[u] = fa ; for(int i = head[u] ;i != -1 ;i = E[i].next) { int v = E[i].v ; if(v == fa) continue ; dfs_find(v ,u) ; siz[u] += siz[v] ; if(siz[son[u]] < siz[v]) son[u] = v ; } } void dfs_time(int u ,int fa) { ti[u] = idx++ ; top[u] = fa ; if(son[u]) dfs_time(son[u] ,top[u]) ; for(int i = head[u] ;i != -1 ;i = E[i].next) { int v = E[i].v ; if(v == father[u] || v == son[u]) continue ; dfs_time(v ,v) ; } } struct node { int le ,rt ,Mi ,Mx ,add ; }T[MX*4] ; void build(int x ,int le ,int rt) { T[x].le = le ; T[x].rt = rt ; T[x].Mi = INF ; T[x].Mx = -INF ; T[x].add = 0 ; if(le == rt) return ; int Mid = (le + rt)>>1 ; build(L(x) ,le ,Mid) ; build(R(x) ,Mid+1 ,rt) ; } void push_down(int x) { if(T[x].le == T[x].rt) return ; if(T[x].add) { T[L(x)].Mi = -T[L(x)].Mi ; T[L(x)].Mx = -T[L(x)].Mx ; swap(T[L(x)].Mi ,T[L(x)].Mx) ; T[R(x)].Mi = -T[R(x)].Mi ; T[R(x)].Mx = -T[R(x)].Mx ; swap(T[R(x)].Mi ,T[R(x)].Mx) ; T[L(x)].add ^= 1 ; T[R(x)].add ^= 1 ; T[x].add = 0 ; } } void push_up(int x) { T[x].Mi = min(T[L(x)].Mi ,T[R(x)].Mi) ; T[x].Mx = max(T[L(x)].Mx ,T[R(x)].Mx) ; } void section(int x ,int le ,int rt) // 更新某个区间 { if(T[x].le == le && T[x].rt == rt) { T[x].add ^= 1 ; T[x].Mi = -T[x].Mi ; T[x].Mx = -T[x].Mx ; swap(T[x].Mi ,T[x].Mx) ; return ; } if(T[x].le == T[x].rt) return ; push_down(x) ; int Mid = (T[x].le + T[x].rt)>>1 ; if(le > Mid) section(R(x) ,le ,rt) ; else if(rt <= Mid) section(L(x) ,le ,rt) ; else { section(L(x) ,le ,Mid) ; section(R(x) ,Mid+1 ,rt) ; } push_up(x) ; } void update(int x ,int pos ,int w) { if(T[x].le == T[x].rt) { T[x].Mi = w ; T[x].Mx = w ; T[x].add = 0 ; return ; } push_down(x) ; int Mid = (T[x].le + T[x].rt)>>1 ; if(pos <= Mid) update(L(x) ,pos ,w) ; else update(R(x) ,pos ,w) ; push_up(x) ; } int Query(int x ,int le ,int rt) // 询问某个区间 { if(T[x].le == le && T[x].rt == rt) return T[x].Mx ; push_down(x) ; int Mid = (T[x].le + T[x].rt)>>1 ; if(le > Mid) return Query(R(x) ,le ,rt) ; else if(rt <= Mid) return Query(L(x) ,le ,rt) ; else return max(Query(L(x) ,le ,Mid) ,Query(R(x) ,Mid+1 ,rt)) ; push_up(x) ; } int LCA(int u ,int v) { if(u == v) return 0 ; int ans = -INF ; while(top[u] != top[v]) { if(dep[top[u]] < dep[top[v]]) swap(u ,v) ; ans = max(ans ,Query(1 ,ti[top[u]] ,ti[u])) ; u = father[top[u]] ; } if(dep[u] > dep[v]) swap(u ,v) ; if(u != v) ans = max(ans ,Query(1 ,ti[u]+1 ,ti[v])) ; return ans ; } void change(int u ,int v) { while(top[u] != top[v]) { if(dep[top[u]] < dep[top[v]]) swap(u ,v) ; section(1 ,ti[top[u]] ,ti[u]) ; u = father[top[u]] ; } if(dep[u] > dep[v]) swap(u ,v) ; section(1 ,ti[u]+1 ,ti[v]) ; } int main() { int Tx ; scanf("%d" ,&Tx) ; while(Tx--) { scanf("%d" ,&n) ; num = 0 ; memset(head ,-1 ,sizeof(head)) ; for(int i = 1 ;i < n ; ++i) { scanf("%d%d%d" ,&e[i].u ,&e[i].v ,&e[i].w) ; addedge(e[i].u ,e[i].v) ; } dep[1] = 0 ; siz[0] = 0 ; dfs_find(1 ,1) ; idx = 1 ; dfs_time(1 ,1) ; build(1 ,2 ,n) ; for(int i = 1 ;i < n ; ++i) { if(dep[e[i].u] < dep[e[i].v]) swap(e[i].u ,e[i].v) ; update(1 ,ti[e[i].u] ,e[i].w) ; } int x ,y ; char s[10] ; while(true) { scanf("%s" ,s) ; if(s[0] == 'D') break ; scanf("%d%d" ,&x ,&y) ; if(s[0] == 'C') update(1 ,ti[e[x].u] ,y) ; else if(s[0] == 'N') change(x ,y) ; else if(s[0] == 'Q') cout<<LCA(x ,y)<<endl ; } } return 0 ; }
POJ 3237 Tree
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。