- 倍增求LCA
1 #include<cstdio> 2 #include<iostream> 3 #define re register 4 #define in inline 5 #define N 500010 6 #define M 500010 7 using namespace std; 8 in int read(){ 9 int x=0,f=1; char c=getchar(); 10 while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*f; 13 } 14 struct node{ 15 int next,to; 16 }edge[M<<1]; 17 int n,q,s,cnt; 18 int head[M<<1],f[25][N],dep[N]; 19 20 in void add(int x,int y){ 21 edge[++cnt].next=head[x]; 22 edge[cnt].to=y; 23 head[x]=cnt; 24 } 25 26 void dfs(int u,int deep){ 27 dep[u]=deep; 28 for(re int i=head[u];i;i=edge[i].next){ 29 int v=edge[i].to; 30 if(!dep[v]) dfs(v,deep+1); 31 f[0][v]=u; //特别注意:需在dfs后更新,不然会被更新回去 32 } //无向图中要保持向根性,所以if(!dep[v])也必不可少 33 } 34 35 in int lca(int x,int y){ 36 if(dep[x]<dep[y]) swap(x,y); 37 for(int i=20;i>=0;i--){ //跳至同一深度 38 if(dep[f[i][x]]>=dep[y]) 39 x=f[i][x]; 40 if(x==y) return x; //跳至同一点(x),x即是lca 41 } 42 43 for(int i=20;i>=0;i--){ 44 if(f[i][x]!=f[i][y]) //不是同一点,往上跳 45 x=f[i][x],y=f[i][y]; 46 } 47 return f[0][x]; //同深度不同点的父节点,即lca 48 } 49 50 int main() 51 { 52 n=read(),q=read(),s=read(); 53 for(re int i=1;i<n;i++){ 54 int u=read(),v=read(); 55 add(u,v),add(v,u); 56 } 57 f[0][s]=s; 58 dfs(s,1); 59 for(re int i=1;(1<<i)<=n;i++) //'x<<y' 表示 "x左移2^y" 60 for(re int j=1;j<=n;j++) 61 f[i][j]=f[i-1][f[i-1][j]]; 62 for(re int i=1;i<=q;i++){ 63 int x=read(),y=read(); 64 printf("%d\n",lca(x,y)); 65 } 66 return 0; 67 }
- 树上差分
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define re register 5 #define in inline 6 #define N 50010 7 using namespace std; 8 int read(){ 9 int x=0,f=1; char c=getchar(); 10 while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*f; 13 14 } 15 struct node{ 16 int next,to; 17 }edge[N<<1]; 18 int n,m,ans,sum,cnt; 19 int head[N<<1],p[N],dep[N],f[N][25]; 20 21 in void add(int x,int y){ 22 edge[++cnt].next=head[x]; 23 edge[cnt].to=y; 24 head[x]=cnt; 25 } 26 in void solve(int u,int fa){ 27 dep[u]=dep[fa]+1,f[u][0]=fa; 28 for(int i=0;f[u][i];i++) f[u][i+1]=f[f[u][i]][i]; 29 for(int i=head[u];i;i=edge[i].next){ 30 int v=edge[i].to; 31 if(v!=fa) solve(v,u); 32 } 33 } 34 in int LCA(int u,int v){ 35 if(dep[u]>dep[v]) swap(u,v); 36 for(re int i=20;i>=0;i--) if(dep[u]<=dep[v]-(1<<i)) v=f[v][i]; 37 if(u==v) return u; 38 for(re int i=20;i>=0;i--) if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i]; 39 return f[u][0]; 40 } 41 in void get(int u,int fa){ 42 for(int i=head[u];i;i=edge[i].next){ 43 int v=edge[i].to; 44 if(v!=fa){ 45 get(v,u); 46 p[u]+=p[v]; 47 } 48 } 49 ans=max(ans,p[u]); 50 } 51 int main() 52 { 53 n=read(),m=read(); 54 for(re int i=1;i<n;i++){ 55 int u=read(),v=read(); 56 add(u,v),add(v,u); 57 } 58 solve(1,0); 59 for(re int i=1;i<=m;i++){ 60 int u=read(),v=read(); 61 int lca=LCA(u,v); 62 p[u]++,p[v]++,p[lca]--,p[f[lca][0]]--; 63 } 64 get(1,0); 65 printf("%d\n",ans); 66 return 0; 67 }