1. 程式人生 > >[Tjoi2016&Heoi2016] 樹

[Tjoi2016&Heoi2016] 樹

fat lse get isdigit for 復雜 truct temp edge

[題目鏈接]

https://www.lydsy.com/JudgeOnline/problem.php?id=4551

[算法]

樹鏈剖分

時間復雜度 : O(QlogN)

[代碼]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010

struct Node
{
        int l , r;
        bool flg;
} Tree[MAXN << 2];
struct edge
{
        int to , nxt;
} e[MAXN 
<< 1]; int n , q , timer , tot; int size[MAXN],top[MAXN],dfn[MAXN],head[MAXN],son[MAXN],father[MAXN],rev[MAXN]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void
read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - 0; x *= f; } inline void addedge(int u,int v) { tot++; e[tot] = (edge){v,head[u]}; head[u]
= tot; } inline void dfs1(int u) { size[u] = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (v == father[u]) continue; father[v] = u; dfs1(v); size[u] += size[v]; if (size[v] > size[son[u]]) son[u] = v; } } inline void dfs2(int u,int tp) { dfn[u] = ++timer; rev[timer] = u; top[u] = tp; if (son[u]) dfs2(son[u],tp); for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (v != son[u] && v != father[u]) dfs2(v,v); } } inline void update(int index) { Tree[index].flg = Tree[index << 1].flg | Tree[index << 1 | 1].flg; } inline void build(int index,int l,int r) { Tree[index].l = l; Tree[index].r = r; Tree[index].flg = false; if (l == r) { if (l == 1) Tree[index].flg = true; return; } int mid = (l + r) >> 1; build(index << 1,l,mid); build(index << 1 | 1,mid + 1,r); update(index); } inline void modify(int index,int pos) { if (Tree[index].l == Tree[index].r) { Tree[index].flg = true; return; } int mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= pos) modify(index << 1,pos); else modify(index << 1 | 1,pos); update(index); } inline int query(int index,int l,int r) { if (!Tree[index].flg) return 0; if (Tree[index].l == Tree[index].r) return l; int mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) return query(index << 1,l,r); else if (mid + 1 <= l) return query(index << 1 | 1,l,r); else { int tmp = query(index << 1 | 1,mid + 1,r); if (tmp == 0) tmp = query(index << 1,l,mid); return tmp; } } int main() { scanf("%d%d",&n,&q); for (int i = 1; i < n; i++) { int u , v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs1(1); dfs2(1,1); build(1,1,n); while (q--) { char op[5]; int x; scanf("%s%d",&op,&x); if (op[0] == Q) { int tx = top[x] , pos = 0; while (true) { pos = query(1,dfn[tx],dfn[x]); if (pos != 0) break; x = father[tx]; tx = top[x]; } printf("%d\n",rev[pos]); } else modify(1,dfn[x]); } return 0; }

[Tjoi2016&Heoi2016] 樹