https://www.lydsy.com/JudgeOnline/problem.php?id=4551
https://www.luogu.org/problemnew/show/P4092
这当然是树剖裸题,还可以不写线段树用set
(只用set达到一个log是不行的,询问中,中间遇到的路径并不总是整段的轻/重链,可能会有半段的)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<set> 6 using namespace std; 7 #define fi first 8 #define se second 9 #define mp make_pair 10 #define pb push_back 11 typedef long long ll; 12 typedef unsigned long long ull; 13 typedef pair<int,int> pii; 14 struct E 15 { 16 int to,nxt; 17 }e[200100]; 18 int f1[100100],ne; 19 int n,q; 20 void me(int a,int b) 21 { 22 e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne; 23 } 24 int hson[100100],tp[100100],sz[100100],dp[100100]; 25 int ar[100100],lp[100100],f[100100]; 26 struct Cmp 27 { 28 bool operator()(int a,int b) 29 { 30 return dp[a]<dp[b]; 31 } 32 }; 33 set<int,Cmp> t2[100100];//以此点为top的链上所有标记点 34 void dfs1(int u,int fa) 35 { 36 sz[u]=1; 37 for(int k=f1[u];k;k=e[k].nxt) 38 if(e[k].to!=fa) 39 { 40 dp[e[k].to]=dp[u]+1; 41 dfs1(e[k].to,u); 42 sz[u]+=sz[e[k].to]; 43 if(sz[e[k].to]>sz[hson[u]]) 44 hson[u]=e[k].to; 45 } 46 } 47 void dfs2(int u,int fa) 48 { 49 ar[++ar[0]]=u;lp[u]=ar[0]; 50 f[u]=fa; 51 if(u==hson[fa]) tp[u]=tp[fa]; 52 else tp[u]=u; 53 if(hson[u]) dfs2(hson[u],u); 54 for(int k=f1[u];k;k=e[k].nxt) 55 if(e[k].to!=fa&&e[k].to!=hson[u]) 56 dfs2(e[k].to,u); 57 } 58 int main() 59 { 60 int i,a,b; 61 char tmp[10]; 62 scanf("%d%d",&n,&q); 63 for(i=1;i<n;i++) 64 { 65 scanf("%d%d",&a,&b); 66 me(a,b);me(b,a); 67 } 68 dfs1(1,0);dfs2(1,0); 69 //for(i=1;i<=n;i++) printf("%d ",f[i]); 70 //puts("b"); 71 //for(i=1;i<=n;i++) printf("%d ",ar[i]); 72 //puts("c"); 73 t2[1].insert(1);//tag[1]=1; 74 while(q--) 75 { 76 scanf("%s",tmp); 77 if(tmp[0]=='C') 78 { 79 scanf("%d",&a); 80 t2[tp[a]].insert(a); 81 } 82 else 83 { 84 scanf("%d",&a); 85 set<int,Cmp>::iterator it; 86 while(1) 87 { 88 it=t2[tp[a]].upper_bound(a); 89 if(it!=t2[tp[a]].begin()) 90 { 91 --it; 92 printf("%d ",*it); 93 break; 94 } 95 a=f[tp[a]]; 96 } 97 } 98 } 99 return 0; 100 }