[HEOI2016/TJOI2016]树
题目大意:
给定一棵$n(n\le10^5)$个结点的以$1$为根的树,初始时$1$为标记结点。有$m(m\le10^5)$次操作,操作包含以下两种:
1.将点$x$打上标记;
2.询问点$x$到根路径上离$x$最近的标记点。
思路:
树链剖分线段树单点修改,区间询问DFS序最大标记点。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 inline char getalpha() { 12 register char ch; 13 while(!isalpha(ch=getchar())); 14 return ch; 15 } 16 const int N=1e5+1; 17 int h[N],size[N],son[N],dfn[N],id[N],par[N],top[N],sz; 18 struct Edge { 19 int to,next; 20 }; 21 Edge e[N<<1]; 22 inline void add_edge(const int &u,const int &v) { 23 e[++sz]=(Edge){v,h[u]};h[u]=sz; 24 } 25 void dfs1(const int &x,const int &par) { 26 size[x]=1; 27 ::par[x]=par; 28 for(int i=h[x];i;i=e[i].next) { 29 const int &y=e[i].to; 30 if(y==par) continue; 31 dfs1(y,x); 32 size[x]+=size[y]; 33 if(size[y]>size[son[x]]) son[x]=y; 34 } 35 } 36 void dfs2(const int &x) { 37 id[dfn[x]=++dfn[0]]=x; 38 top[x]=x==son[par[x]]?top[par[x]]:x; 39 if(son[x]) dfs2(son[x]); 40 for(int i=h[x];i;i=e[i].next) { 41 const int &y=e[i].to; 42 if(y==par[x]||y==son[x]) continue; 43 dfs2(y); 44 } 45 } 46 class SegmentTree { 47 #define _left <<1 48 #define _right <<1|1 49 #define _par >>1 50 private: 51 int val[N<<2]; 52 void push_up(const int &p) { 53 val[p]=std::max(val[p _left],val[p _right]); 54 } 55 public: 56 void modify(const int &p,const int &b,const int &e,const int &x) { 57 if(b==e) { 58 val[p]=x; 59 return; 60 } 61 const int mid=(b+e)>>1; 62 if(x<=mid) modify(p _left,b,mid,x); 63 if(x>mid) modify(p _right,mid+1,e,x); 64 push_up(p); 65 } 66 int query(const int &p,const int &b,const int &e,const int &l,const int &r) const { 67 if(b==l&&e==r) return val[p]; 68 const int mid=(b+e)>>1; 69 int ret=0; 70 if(l<=mid) ret=std::max(ret,query(p _left,b,mid,l,std::min(mid,r))); 71 if(r>mid) ret=std::max(ret,query(p _right,mid+1,e,std::max(mid+1,l),r)); 72 return ret; 73 } 74 #undef _left 75 #undef _right 76 #undef _par 77 }; 78 SegmentTree t; 79 inline int query(int x) { 80 int ret=0; 81 while(!ret) { 82 ret=t.query(1,1,dfn[0],dfn[top[x]],dfn[x]); 83 x=par[top[x]]; 84 } 85 return ret; 86 } 87 int main() { 88 const int n=getint(),m=getint(); 89 for(register int i=1;i<n;i++) { 90 const int u=getint(),v=getint(); 91 add_edge(u,v); 92 } 93 dfs1(1,0); 94 dfs2(1); 95 t.modify(1,1,n,1); 96 for(register int i=0;i<m;i++) { 97 const char opt=getalpha(); 98 const int x=getint(); 99 if(opt=='C') t.modify(1,1,n,dfn[x]); 100 if(opt=='Q') printf("%d\n",id[query(x)]); 101 } 102 return 0; 103 }