Description
一棵树有黑白点,求最近黑点祖先。
Solution
树链剖分。
我居然敲了15min?
Code
/************************************************************** Problem: 4551 User: BeiYu Language: C++ Result: Accepted Time:1972 ms Memory:11952 kb ****************************************************************/ #include <bits/stdc++.h> using namespace std; #define mpr make_pair #define x first #define y second #define debug(a) cout<<(#a)<<"="<<a<<" " //#define lc(o) ch[o][0] //#define rc(o) ch[o][1] #define lc (o<<1) #define rc (o<<1|1) #define mid ((l+r)>>1) typedef long long LL; typedef pair<int,int> pr; typedef vector<int> Vi; typedef vector<LL> Vl; typedef vector<string> Vs; const int N = 100500; const int M = N<<2; const int oo = 0x3fffffff; const LL OO = 1e18; inline LL in(LL x=0,char ch=getchar(),int v=1) { while(ch>‘9‘ || ch<‘0‘) v=ch==‘-‘?-1:v,ch=getchar(); while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*v; } /*end*/ int n,q; int p[N],rp[N],mk[N]; struct SegmentTree { int d[M]; void Modify(int o,int l,int r,int x) { if(l==r) { d[o]=l;return; } if(x<=mid) Modify(lc,l,mid,x); else Modify(rc,mid+1,r,x); d[o]=max(d[lc],d[rc]); } int Query(int o,int l,int r,int L,int R) { if(L<=l && r<=R) return d[o]; int res=0; if(L<=mid) res=max(res,Query(lc,l,mid,L,R)); if(R>mid) res=max(res,Query(rc,mid+1,r,L,R)); return res; } }py; namespace Tree { int cnt; int d[N],f[N],top[N],sz[N],sn[N]; vector<int> g[N]; void AddEdge(int u,int v) { g[u].push_back(v),g[v].push_back(u); } void DFS1(int u,int fa) { d[u]=d[fa]+1,sz[u]=1,sn[u]=0; for(int i=0,v;i<(int)g[u].size();i++) if((v=g[u][i])!=fa) { DFS1(v,u),sz[u]+=sz[v],f[v]=u; if(!sn[u] || sz[sn[u]]<sz[v]) sn[u]=v; } } void DFS2(int u,int fa,int tp) { p[u]=++cnt,rp[cnt]=u,top[u]=tp; if(sn[u]) DFS2(sn[u],u,tp); for(int i=0,v;i<(int)g[u].size();i++) if((v=g[u][i])!=fa && v!=sn[u]) DFS2(v,u,v); } void init() { DFS1(1,1),DFS2(1,1,1); py.Modify(1,1,n,1); mk[1]=1; } int Query(int u) { int f1=top[u],res=0; for(;u;) { res=py.Query(1,1,n,p[f1],p[u]); if(res) return rp[res]; u=f[f1],f1=top[u]; }return 1; } } int main() { n=in(),q=in(); for(int i=1;i<n;i++) { int x=in(),y=in(); Tree::AddEdge(x,y); } Tree::init(); for(int i=1;i<=q;i++) { char opt[15];int x; scanf("%s",opt); if(opt[0]==‘C‘) { x=in(); if(!mk[x]) mk[x]=1,py.Modify(1,1,n,p[x]); } else { x=in(); printf("%d\n",Tree::Query(x)); } }return 0; }
时间: 2024-11-08 21:58:15